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

inline uint8_t HMCAD_Cgain_dB(uint8_t dB)
{
    return (dB <= 12) ? dB : 0;
}

Test = HMCAD_Cgain_dB(11);

спокойно заносит в Test число 11, не производя никаких run-time вычислений. Хватило же интеллекта понять.

Нет, при уровне оптимизации 0 вызывает некую функцию вот такого имени _ZN12hmcad1511_ns14HMCAD_Cgain_dBEh. Но не в этом суть. 

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

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

Какой код? Нет никакого кода (не компилируется же). А для показанной здесь функции:

;;;96         Test = HMCAD_Cgain_dB(11);
0000f0  6001              STR      r1,[r0,#0]  ; Test
0000f2  2100              MOVS     r1,#0
;;;97         Test = HMCAD_Cgain_dB(13);
0000f4  6001              STR      r1,[r0,#0]  ; Test

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


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

inline - это по сути обычная runtime функция, поэтому внутри нее не прокатит никакой static_assert. Причем абсолютно до лампочки, если значения известны на этапе компиляции. 

Замените inline на constexpr и тогда компилятор перестанет ругаться на static_assert

 

 

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


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

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

Замените inline на constexpr и тогда компилятор перестанет ругаться на static_assert

Ничего не меняется. Да и не может измениться, AHTOXA разъяснил.

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


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

11 minutes ago, ViKo said:

Ничего не меняется. Да и не может измениться, AHTOXA разъяснил.

Посмотрите пример от AHTOXA еще раз внимательнее.

 

 

 

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


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

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

Походу вы все еще не поняли разницу между про compile-time и runtime выражениями.

Заканчивайте фантазировать и импровизировать. Мне нужны советы, а не оценки моих умений.

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


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

15 minutes ago, ViKo said:

Мне нужны советы,

уже все прозвучало:

 

1 hour ago, AHTOXA said:

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

 

1 hour ago, Forger said:

Хотите делать проверку входных параметров некой функции (не макроса), то делайте это руками 

 

Повторюсь: найдите реализацию static_assert и все станет сразу понятно.

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


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

17 часов назад, Forger сказал:

Убираю const - ругается линкер как и должен. Не понимаю. Пора читать мануалы и мне

 

17 часов назад, Forger сказал:

Для данной ситуации нет никакой разницы между C и C++. Вы используете примитивные вещи из голого С. Конечно они будут работать в С++.

 

По поводу const есть принципиальная разница между С и С++. const объекты в С - это обычные объекты с внешним связыванием (external linkage) по умолчанию. А в С++ const объекты по умолчанию имеют внутреннее связывание (internal linkage). Сишное поведение можно привести к плюсовому, указав явно static, а плюсовое к сишному, указав extern

 

Такое отличие в С++ было введено специально, чтобы можно было свести к минимуму использование макросов для задания литералов/"констант". Т.е. если в плюсовом файле объявить константный объект, и в коде нигде нет операции взятия адреса этого объекта, то компилятор имеет право (и именно так и делают все вменяемые компиляторы) не инстанцировать объект вообще, а просто использовать его значение - внутреннее связывание гарантирует, что за пределами данной единицы компиляции на этот объект тоже никто не может сослаться, поэтому проблем с линковой тоже нет.

 

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

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


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

18 hours ago, Forger said:

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

В линкере кейла существует какой-то странный костыль - подобный код собирается нормально. Какой магией он "схлопывает" два объекта в один, я не знаю.

Была как-то тема "написал код в кейле, переношу в гцц, памагите, неработает!!", сам я вопрос не исследовал.

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


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

4 minutes ago, esaulenka said:

В линкере кейла существует какой-то странный костыль - подобный код собирается нормально. Какой магией он "схлопывает" два объекта в один, я не знаю.

Была как-то тема "написал код в кейле, переношу в гцц, памагите, неработает!!", сам я вопрос не исследовал.

Да keil тут ни при чем, причину коллега выше постом все отлично расписал.

Но попробуйте убрать квалификатор const хотя бы у одного объекта в h-файле и получите закономерные ошибки линковки (на всякий случай проверил в arm compiler v6).

 

Стараюсь где возможно вместо const использовать constexpr. Сокращаю зону видимости каждого из constexpr настолько, насколько это допустимо.

Классические #define у меня остались только в одном файле (GlobalSetting.h), но причина проста - у Keil есть очень удобный Configuration wizard, который умеет парсить только h-файлы, увы, лишь на базе #define :(

 

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


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

12 часов назад, AHTOXA сказал:

Так что компилятор ругается правильно. Вы можете проверить результат вызова функции, присвоив его constexpr-переменной:


static constexpr uint8_t gain = HMCAD_Cgain_dB(11);

static_assert(gain <= 12, "Gain in dB is too large");

Хорошо, так работает. А как бы запихнуть это в одно целое? В виде макро можно. А в виде функции - никак?

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


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

5 minutes ago, Forger said:

Да keil тут ни при чем

Стряхнул пыль с MDK 5.14 (другого нет, да и этот несколько лет не запускал). Ругается, как и положено.

Действительно, нельзя верить всему, что пишут в интернетах :-( Извините.

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


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

13 minutes ago, ViKo said:

Хорошо, так работает. А как бы запихнуть это в одно целое? В виде макро можно. А в виде функции - никак?

Тут как в известной поговорке - "и рыбку съесть и на ... сесть:acute:

Используйте вместо static_assert что-то другое, которое умеет работать в runtime.

 

Например, сыпет сообщения в консоль или файл. Рекомендую RTT от segger, просто и не требует доп. портов, кроме SWD канала для отладчика.

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


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

36 минут назад, ViKo сказал:

Хорошо, так работает. А как бы запихнуть это в одно целое? В виде макро можно. А в виде функции - никак?

Можно использовать шаблонную функцию:

template <uint8_t i>
uint8_t HMCAD_Cgain_dB()
{
  static_assert(i<12, "gain too big!");
  return i;
}

Применять так:

uint8_t gain = HMCAD_Cgain_dB<11>();

 

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


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

То есть, явно создали экземпляр шаблонной функции, но вместо типа используем константу? Кто автор сей чудесной конструкции? В учебниках не нашел, и сам бы никогда не догадался. 

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


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

Да, это называется не-типовой параметр шаблона.

Я же правильно понимаю, что у вас эта функция вызывается один раз в программе, с константным параметром? И вы хотите проверить то, что параметр находится в заданных пределах во время компиляции? Тогда эта функция подходит.

Или можно сделать шаблонную структуру с константным членом:

template <unsigned busFreq>
struct FreqCalculator
{
    static_assert(busFreq < 400, "Bus freq too high");
    static constexpr unsigned ahbFreq { busFreq };
    static constexpr unsigned apb1Freq { busFreq / 2 };
    static constexpr unsigned apb2Freq { busFreq };
}

И потом, где-то в общем заголовочном файле:

using CpuFreq = FreqCalculator<200>;

и использовать в любом месте:

auto freq = CpuFreq::apb1Freq;

 

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


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

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

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

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

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

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

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

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

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

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