Перейти к содержанию
    

Плавный переход C -> C++ под МК

1 минуту назад, Arlleex сказал:

Очень познавательно.

Если вопрос был про то, как namespace использовать, так, вроде, достаточно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, ViKo сказал:

Если вопрос был про то, как namespace использовать, так, вроде, достаточно.

А вопрос был в этом?:bye:

Так. Видимо, я немножечко туплю. friend-функциям не передается this по умолчанию, я должен передать его сам?

P.S. Разобрался. Но в итоге понял, что лучше создать приватную функцию-член и вызывать ее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос.

Почему на это неявное "сужение" int -> unsigned int компилятор не ругается

u32 i = -1; // ok

а вот когда -1 появляется в инициализаторе массива, то получаю ошибку

u32 i[] = {-1}; // error
Цитата

sources/drivers/can.cpp(128): error: constant expression evaluates to -1 which cannot be narrowed to type 'u32' (aka 'unsigned int') [-Wc++11-narrowing]


В чем глобальная разница? Ведь битовое представление в памяти не изменяется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 minutes ago, Arlleex said:

Ведь битовое представление в памяти не изменяется.

Используйтся static_cast<u32>(-1) при приведениях типа.

А если нужно вообще делать приведения любого типа к любому несовместимому, то придется применять reinterpret_cast

Вот тут почитайте: https://ru.stackoverflow.com/questions/716240/В-чём-смысл-существования-reinterpret-cast  Особенно обратите внимание на комменты там внизу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, вопрос в другом.

Я не вижу сильно большой разницы в приведенных мною примерах, однако, разница есть и я прошу на нее указать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 minutes ago, Arlleex said:

Я не вижу сильно большой разницы в приведенных мною примерах, однако, разница есть и я прошу на нее указать.

Лень вникать в тонкости архаичного (сишного) приведения типа, т.к. нигде не применяю такое неявное приведение типов.

Но вот тут есть немного: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65801

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 2/16/2022 at 5:25 PM, Arlleex said:

В чем глобальная разница?

Первый вариант - так исторически сложилось с незапамятных времён (а дальше - стандарт соблюдает обратную совместимость). Второй вариант - неявное преобразование типов сознательно запретили, из соображений, что оно противоречит общей идее С++ о строгой типизации.

Подробнее можно прочитать в предложении о введении такой инициализации: https://www.stroustrup.com/N1919-initializer_lists.pdf

Только не спрашивайте, как это всё работало до 2005 года ;-) (точнее, 2011, оно попало в стандарт C++11).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хочу вот еще что понять. Нафига, а главное зачем, в C++ столько всяких cast-ов?:wacko2: В чем минус обыкновенных Си-шных приведений? Я вот немного попрактиковался и пришел к выводу, что плюсовые cast-ы тупо лишь синтаксически громоздкие и выгоды в них нет никакой. Хотелось бы увидеть пример, почему нужно отказаться от приведений в стиле Си в угоду плюсовым.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

26 minutes ago, Arlleex said:

Нафига, а главное зачем, в C++ столько всяких cast-ов?:wacko2: В чем минус обыкновенных Си-шных приведений?

C каст неоднозначный. В зависимости от типа того, что приводится и того, к чему приводится он может работать как static_cast<>() или reinterpret_cast<>()

Плюсовые касты однозначны, они работают одинаково вне зависимости от типов.

const_cast<>() добавляет контроль за тем, что при приведении не поменяли случайно сам тип (в C можно ошибиться с типом при приведении и случайно поменять не только константность - никакого контроля нет)

dynamic_cast<>() в С вообще отсутствует

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Arlleex said:

Нафига, а главное зачем, в C++ столько всяких cast-ов?

Они практически не нужны, если код написан правильно. Имхо "cast" - это всегда некий костыль.

У меня он применяется в некоторых местах в низкоуровневом коде - всякие там обертки вокруг чужого c-кода. Драйверы и т.п. 

А в самом коде этих cast нет. Не требуются. А приведение типов в стиле "C" уже давно не использую. От вредных привычек лучше сразу избавляться ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну а как без них?

Вот, например, есть класс работы с CAN-периферией. В классе есть функция установки битовой скорости, причем ее можно выбрать из списка доступных

class cCAN {
  public:
    enum class eBitRate : u32 {
      NOINIT, n10,  n20,  n50,
              n100, n125, n250,
              n500, n800, n1000
    };
    s32 setBitRate(eBitRate bitRate);
};


Сам битрейт прилетает извне (по другому интерфейсу) в виде обычного целого числа от 0 до 8 (0 - 10кбит/с, ..., 8 - 1Мбит/с).
Но, кроме того, где-то в ПО используется и setBitRate(cCAN::eBitRate::n500), т.е. чтобы удобно можно было задавать только то, что позволяет драйвер.

Не хочется эту гору if() ... else if() ... else для перекодирования. Хочется как-то просто

setBitRate((cCAN::eBitRate)(br + 1));

а приходится юзать монстроподобный синтаксис

setBitRate(static_cast<cCAN::eBitRate>(br + 1));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

23 minutes ago, Arlleex said:

Ну а как без них?

В своих CAN драйверах использую несколько иной подход:

namespace stm32f4
{
	class CAN
	{
	public:
.....
		using Bitrate = enum { BAUD_10K, BAUD_20K, BAUD_25K , BAUD_50K, BAUD_100K, BAUD_250K, BAUD_500K, BAUD_750K, BAUD_1M, BAUD_AUTO } ;
....	
		void setBitrate(Bitrate);
...
  

"if else" не нужен, в данном случае вместо него трудится switch-case. Их тут заранее известное кол-во. Все это все равно скрыто внутри драйвера. Отлажено и забыто )

Никакой CAST не нужен. А уже в коде компилятор сразу заругается, если ему попытаться сунуть что-то "левое" в setBitrate( ).

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но разве этот switch-case нагляден? А если там этих возможных вариантов будет сотня-тысяча?

На самом деле можно приводить миллион примеров, когда без явного cast-а лаконично не обойтись.

Примеры.

1. Функция чтения занятого места в программной очереди (FIFO)

// const    u32 bufSize
// volatile u32 rpos, wpos
u32 cSoft::getBusy() const {
  u32 busyLen = wpos;
  if((s32)(busyLen -= rpos) < 0)
    busyLen += bufSize;
  return busyLen;
}

Указатели головы и хвоста (wpos, rpos) по своему смыслу не могут быть знаковыми целыми - поэтому они беззнаковые u32. Однако при вычислении их разницы может получиться отрицательный результат, который нужно обрабатывать именно как знаковый - приведение неизбежно.

2. Запись адресов каких-то объектов в регистры периферии

// PAR == *(volatile u32 *)0x...
dmaCtrl.hw.str->PAR = (u32)&uartCtrl.hw->DR;


3. Использование функций с несовместимыми указателями

// элементы rxFIFO имеют тип FIFO_TYPE, а
// я помещаю в эту очередь msg типа sCANMsg
void cCAN::svcOnRxEvt() const {
  const u32 msgLen = sizeof(sCANMsg) / sizeof(FIFO_TYPE);
  while(...) {
    if(canCtrl.rxFIFO->getFree() >= msgLen) {
      __ALIGNED(4) sCANMsg msg;
      ...
      canCtrl.rxFIFO->write((FIFO_TYPE *)&msg, msgLen);
    }
  }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...