AHTOXA 18 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба В c++ переменные, объявленные const, по умолчанию имеют внутреннее связывание. Поэтому в том случае, когда вы объявляете const int x = 3; в *.h файле, то можете смело включать его в любое количество cpp файлов. Это будет примерно аналогично тому, если бы вы в каждом из cpp файлов объявили свою статическую переменную. В си не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба Спасибо, "понел"! А вот еще загадка: inline constexpr uint8_t HMCAD_Cgain_dB(uint8_t dB) { static_assert(dB <= 12, "Gain in dB is too large"); return dB; } Test = HMCAD_Cgain_dB(11); ...: error: #28: expression must have a constant value static_assert(dB <= 12, "Gain in dB is too large"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба Если не требуется статическое размещение, можно уложить константы в отдельный enum, плюсы: не использует магию препроцессора, учитывает неймспейсы, невозможно размазать константы по всему файлу - они всегда в одном месте, можно положить внутрь класса - явно показав где константа используется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 1 час назад, ViKo сказал: А вот еще загадка: inline constexpr uint8_t HMCAD_Cgain_dB(uint8_t dB) { static_assert(dB <= 12, "Gain in dB is too large"); return dB; } Test = HMCAD_Cgain_dB(11); ...: error: #28: expression must have a constant value static_assert(dB <= 12, "Gain in dB is too large"); Дело в том, что constexpr-функция может вызываться и во время выполнения, как обычная функция. То есть, вполне допустим вызов auto i = getUserInput(); HMCAD_Cgain_dB(i); Так что компилятор ругается правильно. Вы можете проверить результат вызова функции, присвоив его constexpr-переменной: static constexpr uint8_t gain = HMCAD_Cgain_dB(11); static_assert(gain <= 12, "Gain in dB is too large"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба На функцию inline uint8_t HMCAD_Cgain_dB(uint8_t dB) { static_assert(dB <= 12, "Gain in dB is too large"); return dB; } ругается точно так же: expression must have a constant value. Дело не в constexpr или const. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 7 minutes ago, ViKo said: к же: expression must have a constant value. Дело не в constexpr или const. Правильно он ругается: constexpr имеет сходный функционал, как и #define (если грубо), но имеет гораздо больше возможностей. constexpr по сути точно также как и #define парсится еще в препроцессоре, до вызова компилятора, НЕ runtime. Если на этапе компиляции нельзя посчитать значения внутри constexpr -функции, то будет вполне логичная ошибка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 6 минут назад, ViKo сказал: На функцию inline uint8_t HMCAD_Cgain_dB(uint8_t dB) { static_assert(dB <= 12, "Gain in dB is too large"); return dB; } ругается точно так же: expression must have a constant value. Дело не в constexpr или const. Вы ещё раз перечитайте мой ответ:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба Сейчас там никаким constexpr не пахнет. Проблема в inline и static_assert. 2 минуты назад, AHTOXA сказал: Вы ещё раз перечитайте мой ответ Ваше разъяснение понятно, однако, у меня в функцию передается константа. Решение же не видится мне красивым и логичным. Проще просто забить на проверку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 3 minutes ago, ViKo said: Сейчас там никаким constexpr не пахнет. И то верно )) Quote Проблема в inline и static_assert. inline тут ни при чем, откройте реализацию static_assert, все станет понятно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба Немного разовью. static_assert - это проверка времени компиляции. Поэтому проверять оно может только значения, вычисляемые во время компиляции. Переменная constexpr - гарантированно вычисляется во время компиляции. Поэтому такая конструкция будет работать всегда: constexpr int bufferSize = sizeof(SomeStruct)/sizeof(int); static_assert(bufferSize < 20); Вы же пытаетесь вставить static_assert в функцию. Даже если эта функция constexpr, она может быть вызвана во время выполнения программы, поэтому внутри функции проверка её параметра при помощи static_assert() не срабатывает. Выход - присвоить результат выполнения constexpr-функции constexpr-переменной и проверить значение этой переменной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 2 минуты назад, Forger сказал: inline тут ни при чем Да, не при чем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба Вот в макрофункции с помощью static_assert я могу устроить требуемую проверку, а в функциях, значит, нет. #define DWT_DELAY_RESTART(Time); \ static_assert((Time * SYSCLK + 999999999uLL) / 1000000000uLL < 1uLL << 32, "Over Delay"); \ cst = DWT->CYCCNT; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 7 minutes ago, ViKo said: Вот в макрофункции с помощью static_assert я могу устроить требуемую проверку, а в функциях, значит, нет. Это абсолютно логично и очевидно: "макрофункции" вычисляются еще на этапе компиляции, точнее на этапе работы препроцессора (compile-time), а обычные функции - в процессе работы кода (runtime). Хотите делать проверку входных параметров некой функции (не макроса), то делайте это руками - через банальный "if". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба Зато не логично, что на этапе компиляции в inline функцию передается константа 11, а static_assert отказывается сравнивать ее с 12. 5 минут назад, Forger сказал: делайте это руками - через банальный "if" в соседней функции делаю через ? : Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 16 июля, 2019 Опубликовано 16 июля, 2019 · Жалоба 8 minutes ago, ViKo said: Зато не логично, что на этапе компиляции в функцию передается константа 11, а static_assert отказывается сравнивать ее с 12. Такое возможно лишь с constexpr функцией или макросом на базе define. В обычной функции такое не прокатит. Обычная функция - это набор команд, кода внутри МК. Обычная функция (inline в т. ч.) понятия не имеет, что именно придет ей на вход и потому применить внутри такой функции static_assert в принципе невозможно. О чем однозначно говорит компилятор. 8 minutes ago, ViKo said: на этапе компиляции в inline функцию передается константа 11 Где именно? Покажите код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться