Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: build-time проверка условия
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
jcxz
В своих проектах беру себе за правило чтобы, если имеются какие-то дефайны, задающие некоторые условия компиляции, то где-то была проверка на допустимость значений этих дефайнов и, если они вне допустимых пределов, проект не собирался бы.
Например: имеется некий дефайн, задающий кол-во элементов массива N (размер элемента L), этот массив передаётся через некий интерфейс, размер кадра которого ограничен некоей величиной M.
В этом случае я добавляю проверку, чтобы: N*L <= M.
Если все величины известны на этапе препроцессора, всё ок - делаю: #if/#error/#endif
Но если контролируемое выражение нельзя рассчитать на этапе препроцессора (например: L=sizeof(...)), то приходится писать что-то вроде:
enum {CheckExp = 1 / ((N*L > M) ? 0: 1)};
в расчёте на ошибку "деление на ноль" при компиляции.
Работает конечно, но может есть более элегантное решение?
ViKo
assert?
http://habrahabr.ru/post/141080/
jcxz
Цитата(ViKo @ Aug 31 2015, 13:21) *
assert?

assert - run-time проверка, мне нужна build-time, см. топик
Чтобы с недопустимыми значениями нельзя было скомпилить.
Kabdim
В С11(gcc-4.6+) есть _Static_assert/static_assert().
http://en.cppreference.com/w/c/language/_Static_assert
SSerge
Можно ещё сослаться на несуществующую глобальную переменную или функцию.
Тогда на этапе сборки линкер её не найдёт и выдаст сообщение.
ViKo
Попробовал в Кейле задать опцию --cpp11, и тогда
static_assert(SYSTICK_LOAD < 1000000, "Check SysTick");
компилируется.
Но не находит функций, определенных в другом файле. Видимо, не соответствует принципам C++.
Kabdim
Звучит как недостаток extern "C" в заголовочных файлах.
ЗЫ Там есть описание велосипедов http://stackoverflow.com/questions/3385515...tic-assert-in-c
CrimsonPig
Цитата(jcxz @ Aug 31 2015, 07:02) *
Работает конечно, но может есть более элегантное решение?


Ну, я давным-давно сделал себе макрос и таскаю его между всеми своими проектами:

#define __ASSERT_COMPILE(x) void __compile_time_assert(int __check[(x)?1:-1])
ViKo
Цитата(Kabdim @ Aug 31 2015, 11:39) *
Звучит как недостаток extern "C" в заголовочных файлах.

Может быть, мне не актуально. Я на C пишу.

Попробовал в Кейле
Код
#include <assert.h>
...
assert(SYSTICK_LOAD < 10000);

и получил
Код
BL       abort

Уже на этапе компиляции. (А если проверяю на число, большее, чем реально высчитывается, то проходит). Так что, можно пользоваться. Правда, выскочит оно только при работе.
jcxz
Цитата(SSerge @ Aug 31 2015, 14:13) *
Можно ещё сослаться на несуществующую глобальную переменную или функцию.
Тогда на этапе сборки линкер её не найдёт и выдаст сообщение.

Как? Приведите пример

Цитата(CrimsonPig @ Aug 31 2015, 14:44) *
Ну, я давным-давно сделал себе макрос и таскаю его между всеми своими проектами:
#define __ASSERT_COMPILE(x) void __compile_time_assert(int __check[(x)?1:-1])

Ну это примерно то же, что и у меня.

Цитата(Kabdim @ Aug 31 2015, 13:48) *
В С11(gcc-4.6+) есть _Static_assert/static_assert().
http://en.cppreference.com/w/c/language/_Static_assert

У меня IAR или CCS. sad.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.