ViKo 1 10 февраля, 2022 Опубликовано 10 февраля, 2022 · Жалоба NS:: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 10 февраля, 2022 Опубликовано 10 февраля, 2022 · Жалоба 7 минут назад, ViKo сказал: NS:: Очень познавательно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 февраля, 2022 Опубликовано 10 февраля, 2022 · Жалоба 1 минуту назад, Arlleex сказал: Очень познавательно. Если вопрос был про то, как namespace использовать, так, вроде, достаточно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 10 февраля, 2022 Опубликовано 10 февраля, 2022 · Жалоба 1 час назад, ViKo сказал: Если вопрос был про то, как namespace использовать, так, вроде, достаточно. А вопрос был в этом? Так. Видимо, я немножечко туплю. friend-функциям не передается this по умолчанию, я должен передать его сам? P.S. Разобрался. Но в итоге понял, что лучше создать приватную функцию-член и вызывать ее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба Вопрос. Почему на это неявное "сужение" 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] В чем глобальная разница? Ведь битовое представление в памяти не изменяется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба 9 minutes ago, Arlleex said: Ведь битовое представление в памяти не изменяется. Используйтся static_cast<u32>(-1) при приведениях типа. А если нужно вообще делать приведения любого типа к любому несовместимому, то придется применять reinterpret_cast Вот тут почитайте: https://ru.stackoverflow.com/questions/716240/В-чём-смысл-существования-reinterpret-cast Особенно обратите внимание на комменты там внизу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба Нет, вопрос в другом. Я не вижу сильно большой разницы в приведенных мною примерах, однако, разница есть и я прошу на нее указать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба 17 minutes ago, Arlleex said: Я не вижу сильно большой разницы в приведенных мною примерах, однако, разница есть и я прошу на нее указать. Лень вникать в тонкости архаичного (сишного) приведения типа, т.к. нигде не применяю такое неявное приведение типов. Но вот тут есть немного: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65801 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 18 февраля, 2022 Опубликовано 18 февраля, 2022 · Жалоба On 2/16/2022 at 5:25 PM, Arlleex said: В чем глобальная разница? Первый вариант - так исторически сложилось с незапамятных времён (а дальше - стандарт соблюдает обратную совместимость). Второй вариант - неявное преобразование типов сознательно запретили, из соображений, что оно противоречит общей идее С++ о строгой типизации. Подробнее можно прочитать в предложении о введении такой инициализации: https://www.stroustrup.com/N1919-initializer_lists.pdf Только не спрашивайте, как это всё работало до 2005 года ;-) (точнее, 2011, оно попало в стандарт C++11). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 22 февраля, 2022 Опубликовано 22 февраля, 2022 · Жалоба Хочу вот еще что понять. Нафига, а главное зачем, в C++ столько всяких cast-ов? В чем минус обыкновенных Си-шных приведений? Я вот немного попрактиковался и пришел к выводу, что плюсовые cast-ы тупо лишь синтаксически громоздкие и выгоды в них нет никакой. Хотелось бы увидеть пример, почему нужно отказаться от приведений в стиле Си в угоду плюсовым. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 22 февраля, 2022 Опубликовано 22 февраля, 2022 · Жалоба 26 minutes ago, Arlleex said: Нафига, а главное зачем, в C++ столько всяких cast-ов? В чем минус обыкновенных Си-шных приведений? C каст неоднозначный. В зависимости от типа того, что приводится и того, к чему приводится он может работать как static_cast<>() или reinterpret_cast<>() Плюсовые касты однозначны, они работают одинаково вне зависимости от типов. const_cast<>() добавляет контроль за тем, что при приведении не поменяли случайно сам тип (в C можно ошибиться с типом при приведении и случайно поменять не только константность - никакого контроля нет) dynamic_cast<>() в С вообще отсутствует Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 22 февраля, 2022 Опубликовано 22 февраля, 2022 · Жалоба 2 hours ago, Arlleex said: Нафига, а главное зачем, в C++ столько всяких cast-ов? Они практически не нужны, если код написан правильно. Имхо "cast" - это всегда некий костыль. У меня он применяется в некоторых местах в низкоуровневом коде - всякие там обертки вокруг чужого c-кода. Драйверы и т.п. А в самом коде этих cast нет. Не требуются. А приведение типов в стиле "C" уже давно не использую. От вредных привычек лучше сразу избавляться ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 22 февраля, 2022 Опубликовано 22 февраля, 2022 · Жалоба Ну а как без них? Вот, например, есть класс работы с 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)); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 22 22 февраля, 2022 Опубликовано 22 февраля, 2022 · Жалоба 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( ). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 165 22 февраля, 2022 Опубликовано 22 февраля, 2022 · Жалоба Но разве этот 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); } } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться