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

STM32F429 и 16-битная SDRAM 16MB /32 MB : практический опыт?

А я вот так реализовал:

#define assert(cond)     (void)assertpass(cond)
#define assertpass(cond) ((cond) ? 1 : 1 / (cond))

 

Run-time ассерты у меня называются trap() со всякими аргументами. Соответственно просто assert - это только статические.

Макрос assert(cond) вызовет ошибку компиляции, если условие cond ложно. Для этого в настройках компилятора нужно переопределить ловушку "Division by zero" с Warning на Error. Двойной щелчок по ошибочному сообщению покажет место в коде, где сработал статический assert(). Если же условие истинно, вычисление отбросится на этапе компиляции, соответственно в итоговый код оно не попадет.

Макрос assertpass(cond) работает аналогично первому, за исключением того, что используется, обычно, в других макросах, допускающих, если можно так выразиться, вычисление в выражениях. Например:

#define ASSERT_RANGE_X(x) ((x) << 5)
#define RANGE_X(x)        ASSERT_RANGE_X(assertpass((x) > 10) * x)

...

func(RANGE_X(7)); // ошибка компиляции
func(RANGE_X(15)); // сработает правильно

 

Придумано не мной, но работает так, что я более, чем доволен:to_become_senile:

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


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

8 часов назад, Arlleex сказал:

А я вот так реализовал:


#define assert(cond)     (void)assertpass(cond)
#define assertpass(cond) ((cond) ? 1 : 1 / (cond))

 

Сейчас Вам тут объяснят, что у Вас всё не по феншую, и вообще - вздор какой-то.  :hysteric:

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


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

#define ASSERT_STATIC(x, n) enum {concatAB(ASSERT_STATIC_, n) = (x) ? 1: 1 / (uint)(x)} //аналогично assert_static(), но для вставки как строка кода, а не как выражение
Объясните, пожалуйста, что делает enum? И что такое строка кода?

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


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

3 часа назад, ViKo сказал:

#define ASSERT_STATIC(x, n) enum {concatAB(ASSERT_STATIC_, n) = (x) ? 1: 1 / (uint)(x)} //аналогично assert_static(), но для вставки как строка кода, а не как выражение
Объясните, пожалуйста, что делает enum? И что такое строка кода?

Если по выражению не понимаете, то попробуйте подставить вместо x выражение результат которого != 0 и скомпилить, а потом выражение результат которого == 0 и опять скомпилить. Увидите разницу.

строка кода - это значит используется так:

...

ASSERT_STATIC(..., 0);  

...

в отличие от выражения (как assert_static()).

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


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

Я вижу ваши макросы один в один, отсюда:

http://www.pixelbeat.org/programming/gcc/static_assert.html

Но мне в Кейле на C99 эти "выкрутасы" ничего не дают. Я не вижу в Build Output ни текстового сообщения, ни номера строки, ни счетчика. Тупо "деление на ноль" или "массив не того размера". Вот и недоумеваю, зачем эти сложности? 

*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'I:\Design\Keil\ARM\ARMCC\Bin'
creating preprocessor file for ll_core.c...
compiling ll_core.c...
Source\LowLayer\ll_core.c(63): error:  #94: the size of an array must be greater than zero
        COMPILE_TIME_ASSERT(SYSTICK_LOAD_VALUE < (1 << 24));
Source\LowLayer\ll_core.c: 0 warnings, 1 error
"Source\LowLayer\ll_core.c" - 1 Error(s), 0 Warning(s).

Да, вижу в C preprocessor listing такую фразу:

typedef char static_assertion_static_assertion_at_line_63[((1 << 24) < (1 << 24)) ? 1 : -1];
    
 Но мне эдакий листинг, как собаке пятая нога.

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


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

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

Но мне в Кейле на C99 эти "выкрутасы" ничего не дают. Я не вижу в Build Output ни текстового сообщения, ни номера строки, ни счетчика. Тупо "деление на ноль" или "массив не того размера". Вот и недоумеваю, зачем эти сложности? 

Если вам они не нужны, зачем тогда используете? Кто-то стоит над вами с палкой и заставляет? "Мыши кололись, плакали, но продолжали жрать кактус".

Или в чём вопрос? я не понимаю....  :wacko2:

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


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

Что-то же надо использовать. Перебираю варианты, не вижу пользы. :sad: Спрашиваю у форума, что вам дают эти "выкрутасы"? 

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


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

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

Что-то же надо использовать. Перебираю варианты, не вижу пользы. :sad: Спрашиваю у форума, что вам дают эти "выкрутасы"? 

То и дают - проверку условий на этапе build-time. И я не использую никакие C99 и иже с ними.

И вообще - те мои макросы Вы выдрали из сообщения предназначенного для приведённого мной примера кода конфигурирования MPU. Вот и попробуйте этот пример скомпилить без них.

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


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

8 минут назад, jcxz сказал:

То и дают - проверку условий на этапе build-time. И я не использую никакие C99 и иже с ними.

И вообще - те мои макросы Вы выдрали из сообщения предназначенного для приведённого мной примера кода конфигурирования MPU. Вот и попробуйте этот пример скомпилить без них.

Что дают эти макросы - понятно. Не понятно, в какой форме и куда они выдают ошибку. Я в Кейле показал - как собаке пятая нога. Может, IAR больше текста выдает? Тогда ладно.

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


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

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

Что дают эти макросы - понятно. Не понятно, в какой форме и куда они выдают ошибку.

Мне текст не нужен. Я по выражению всё вижу. Главное чтоб компиляция не выполнялась при ложном условии.

А если нужен текст его можно в комментарии написать.

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


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

1 минуту назад, jcxz сказал:

Мне текст не нужен. Я по выражению всё вижу. Главное чтоб компиляция не выполнялась при ложном условии.

А если нужен текст его можно в комментарии написать.

А как же __LINE__ , __COUNTER__ ? Вы же здесь обсуждали. Если их не видно, и вообще не нужно, зачем пихать в макрос?

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


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

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

А как же __LINE__ , __COUNTER__ ? Вы же здесь обсуждали. Если их не видно, и вообще не нужно, зачем пихать в макрос?

Затем, что такой макрос может быть использован несколько раз в одной и той же области видимости.

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


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

Пустой разговор. Пойду урежу свой ASSERT до минимального, без всяких конкатенаций, строк, счетчиков.

А еще лучше, пойду куда-нибудь на C++11, только бы не вести пустых разговоров.

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


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

Подтверждаю. Достаточно в опциях файла прописать --cpp11, как появляется возможность пользовать static_assert. Откуда берется функция (и функция ли?), не нашел, в списках функций не значится.

static_assert(SYSTICK_LOAD_VALUE < (1 << 24), "Over");

А также могу пользоваться в любом C конструкцией вида

#if (SYSTICK_LOAD_VALUE >= (1 << 24))
    #error: "Over!"
#endif

Только русских букв Keil в Build Output (у меня) не пишет.

 

 

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


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

Кстати, на cppreference говорят, что static_assert есть и в c11 (не путать с c++11).

Можно не изобретать свои велосипеды, а использовать стандартный, из assert.h

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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