реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> build-time проверка условия
jcxz
сообщение Aug 31 2015, 06:02
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



В своих проектах беру себе за правило чтобы, если имеются какие-то дефайны, задающие некоторые условия компиляции, то где-то была проверка на допустимость значений этих дефайнов и, если они вне допустимых пределов, проект не собирался бы.
Например: имеется некий дефайн, задающий кол-во элементов массива N (размер элемента L), этот массив передаётся через некий интерфейс, размер кадра которого ограничен некоей величиной M.
В этом случае я добавляю проверку, чтобы: N*L <= M.
Если все величины известны на этапе препроцессора, всё ок - делаю: #if/#error/#endif
Но если контролируемое выражение нельзя рассчитать на этапе препроцессора (например: L=sizeof(...)), то приходится писать что-то вроде:
enum {CheckExp = 1 / ((N*L > M) ? 0: 1)};
в расчёте на ошибку "деление на ноль" при компиляции.
Работает конечно, но может есть более элегантное решение?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 31 2015, 07:21
Сообщение #2


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



assert?
http://habrahabr.ru/post/141080/
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 31 2015, 07:39
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Aug 31 2015, 13:21) *
assert?

assert - run-time проверка, мне нужна build-time, см. топик
Чтобы с недопустимыми значениями нельзя было скомпилить.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Aug 31 2015, 07:48
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



В С11(gcc-4.6+) есть _Static_assert/static_assert().
http://en.cppreference.com/w/c/language/_Static_assert

Сообщение отредактировал Kabdim - Aug 31 2015, 07:54
Go to the top of the page
 
+Quote Post
SSerge
сообщение Aug 31 2015, 08:13
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Можно ещё сослаться на несуществующую глобальную переменную или функцию.
Тогда на этапе сборки линкер её не найдёт и выдаст сообщение.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 31 2015, 08:23
Сообщение #6


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Попробовал в Кейле задать опцию --cpp11, и тогда
static_assert(SYSTICK_LOAD < 1000000, "Check SysTick");
компилируется.
Но не находит функций, определенных в другом файле. Видимо, не соответствует принципам C++.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Aug 31 2015, 08:39
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Звучит как недостаток extern "C" в заголовочных файлах.
ЗЫ Там есть описание велосипедов http://stackoverflow.com/questions/3385515...tic-assert-in-c

Сообщение отредактировал Kabdim - Aug 31 2015, 08:42
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Aug 31 2015, 08:44
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502



Цитата(jcxz @ Aug 31 2015, 07:02) *
Работает конечно, но может есть более элегантное решение?


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

#define __ASSERT_COMPILE(x) void __compile_time_assert(int __check[(x)?1:-1])
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 31 2015, 08:45
Сообщение #9


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Kabdim @ Aug 31 2015, 11:39) *
Звучит как недостаток extern "C" в заголовочных файлах.

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

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

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

Уже на этапе компиляции. (А если проверяю на число, большее, чем реально высчитывается, то проходит). Так что, можно пользоваться. Правда, выскочит оно только при работе.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 31 2015, 09:23
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(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
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 19:25
Рейтинг@Mail.ru


Страница сгенерированна за 0.01458 секунд с 7
ELECTRONIX ©2004-2016