Есть ли замена static_assert, которая удовлетворяет стандарту C99?

Я пытался реализовать метод, аналогичный static_assert который определен в стандарте C ++ 11. Основная проблема заключается в том, как компилятор C ++ записывает текстовое сообщение, передаваемое static_assert как const char*? Я могу заставить компилятор написать сообщение как A_is_not_POD, Вот что у меня есть:

#define MY_STATIC_ASSERT(condition, name)         \
typedef char name[(condition) ? 1 : -1];

Но было бы неплохо заставить компилятор написать что-то вроде "Error: A is not POD." Какие-либо предложения?

11

Решение

Не уверен, что понимаю вопрос, но у С11 есть _Static_assert(condition, errmessage), В C99 эта функциональность отсутствовала, но, в зависимости от компилятора, можно было эмулировать. Например. для gcc (к сожалению, clang не поддерживает атрибут (ошибка))

#define MY_STATIC_ASSERT(cnd, descr) ({ \
extern int __attribute__ ((error("static assert failed: (" #cnd ") (" #descr ")"))) \
compile_time_check(void); \
((cnd) ? 0 : compile_time_check()), 0; \
})
4

Другие решения

В стандарте с99 нету «Официальный» способ выполнить статическое утверждение в вашем компиляторе C ++.

«Основная проблема в том, как компилятор C ++ записывает текстовое сообщение, передаваемое в static_assert, как const char *?»

C ++ компилятор обнаруживает ошибку в коде и распечатывает соответствующее сообщение об ошибке на основе стандартного списка сообщений, которые имеются для каждой известной ошибки, с которой он может столкнуться. В c99 компилятор не знает что такое «статическое утверждение ошибкаесть, поэтому вам нужно вызвать некоторые Другой ошибка.

Однако, поскольку создание статических утверждений с помощью компилятора c99 является своего рода хаком, оно не способно распечатывать красивое сообщение об ошибке именно так, как вам нужно.

Для вашего примера

#define MY_STATIC_ASSERT(condition, name)         \
typedef char name[(condition) ? 1 : -1];
MY_STATIC_ASSERT(false, my_error_msg)

вызовет "error: size of array ‘my_error_msg’ is negative" сообщение в НКУ компилятор (и, должно быть, аналогичное сообщение в других компиляторах!). Предоставление массиву сообщения об ошибке для name был способ распечатать свою собственную информацию. Существуют различные другие методы / взломы, которые вы можете сделать специально, такие как плохие шаблоны, перечисления ссылка на сайт

Замечания: вы Можно предоставлять пользовательские сообщения компилятора до C ++ 11, используя препроцессор такие макросы как #error или же #pragma, тем не мение время предварительной обработки это не то же самое, что время компиляции! Препроцессор имеет ограниченную способность оценивать многие выражения и ключевые слова, такие как "if", "sizeof", "return" и так далее не имеют никакого значения для препроцессор, только компилятор. ссылка с некоторым обзором

2