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

В c++ переменные, объявленные const, по умолчанию имеют внутреннее связывание. Поэтому в том случае, когда вы объявляете const int x = 3; в *.h файле, то можете смело включать его в любое количество  cpp файлов. Это будет примерно аналогично тому, если бы вы в каждом из cpp файлов объявили свою статическую переменную.

В си не так.

 

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


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

Спасибо, "понел"!  

А вот еще загадка:

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");

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


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

Если не требуется статическое размещение, можно уложить константы в отдельный enum, плюсы: не использует магию препроцессора, учитывает неймспейсы, невозможно размазать константы по всему файлу - они всегда в одном месте, можно положить внутрь класса - явно показав где константа используется.

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


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

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");


 


 

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


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

На функцию

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.

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


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

7 minutes ago, ViKo said:

к же: expression must have a constant value. Дело не в constexpr или const.

Правильно он ругается: constexpr имеет сходный функционал, как и #define (если грубо), но имеет гораздо больше возможностей.

constexpr по сути точно также как и #define парсится еще в препроцессоре, до вызова компилятора, НЕ runtime.

Если на этапе компиляции нельзя посчитать значения внутри constexpr -функции, то будет вполне логичная ошибка.

 

 

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


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

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.

Вы ещё раз перечитайте мой ответ:)
 

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


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

Сейчас там никаким constexpr не пахнет. Проблема в inline и static_assert.

2 минуты назад, AHTOXA сказал:

Вы ещё раз перечитайте мой ответ

Ваше разъяснение понятно, однако, у меня в функцию передается константа.

Решение же не видится мне красивым и логичным. Проще просто забить на проверку.

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


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

3 minutes ago, ViKo said:

Сейчас там никаким constexpr не пахнет.

И то верно ))

 

Quote

Проблема в inline и static_assert.

inline тут ни при чем, откройте реализацию static_assert, все станет понятно.

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


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

Немного разовью.

static_assert - это проверка времени компиляции. Поэтому проверять оно может только значения, вычисляемые во время компиляции.

Переменная constexpr - гарантированно вычисляется во время компиляции. Поэтому такая конструкция будет работать всегда:

constexpr int bufferSize = sizeof(SomeStruct)/sizeof(int);
static_assert(bufferSize < 20);

Вы же пытаетесь вставить static_assert в функцию. Даже если эта функция constexpr, она может быть вызвана во время выполнения программы, поэтому внутри функции проверка её параметра при помощи static_assert() не срабатывает.

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

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


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

2 минуты назад, Forger сказал:

inline тут ни при чем

Да, не при чем. 

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


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

Вот в макрофункции с помощью static_assert я могу устроить требуемую проверку, а в функциях, значит, нет.

#define DWT_DELAY_RESTART(Time);        \
    static_assert((Time * SYSCLK + 999999999uLL) / 1000000000uLL < 1uLL << 32, "Over Delay");    \
    cst = DWT->CYCCNT; 

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


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

7 minutes ago, ViKo said:

Вот в макрофункции с помощью static_assert я могу устроить требуемую проверку, а в функциях, значит, нет.

Это абсолютно логично и очевидно: "макрофункции" вычисляются еще на этапе компиляции, точнее на этапе работы препроцессора (compile-time), а обычные функции - в процессе работы кода (runtime).

Хотите делать проверку входных параметров некой функции (не макроса), то делайте это руками - через банальный "if".

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


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

Зато не логично, что на этапе компиляции в inline функцию передается константа 11, а static_assert отказывается сравнивать ее с 12. :biggrin:

5 минут назад, Forger сказал:

делайте это руками - через банальный "if"

в соседней функции делаю через ? :

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


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

8 minutes ago, ViKo said:

Зато не логично, что на этапе компиляции в функцию передается константа 11, а static_assert отказывается сравнивать ее с 12. :biggrin:

Такое возможно лишь с constexpr функцией или макросом на базе define.

В обычной функции такое не прокатит. Обычная функция - это набор команд, кода внутри МК. Обычная функция (inline в т. ч.) понятия не имеет, что именно придет ей на вход и потому применить внутри такой функции static_assert в принципе невозможно. О чем однозначно говорит компилятор.

 

 

8 minutes ago, ViKo said:

на этапе компиляции в inline функцию передается константа 11

Где именно? Покажите код.

 

 

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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