Генерация ошибки, если флажок boolean macro не определен
У меня есть несколько файлов конфигурации, каждый из которых содержит определение некоторого логического макроса, который должен быть установлен в 0 или 1. Затем в моем коде я проверяю значение такого макроса, чтобы решить, какую часть кода активировать. Теперь идет сложная часть: я хочу быть уверенным, что заголовок, содержащий определение моего макроса, был включен.
В следующем примере, если я забуду включить заголовочный файл, содержащий определение FOO, компилятор напечатает "мир!", В то время как я хотел бы вместо этого создать ошибку.
//in the configuration header file
#define FOO 1
//in a cpp file
#if FOO //I would like this to generate an error if I forgot to include the header file
#pragma message "Hello"
#else
#pragma message "world!"
#endif
Можно ли добиться такого поведения? Как?
Чтобы уточнить, я не спрашиваю, как генерировать ошибку, если макрос не определен, но если можно преобразовать строку #if FOO
чтобы в то же время он проверял логическое значение и генерировал ошибку, если FOO
не определен.
Дело в том, что разработчики должны знать, что их код должен содержать
SPECIAL_MACRO(FOO)
которые в то же время проверяют логическое значение FOO, как если бы это был оператор #if FOO
, и не позволяли им забыть включение заголовка, определяющего FOO
.
Ответы
Ответ 1
Коллеги (привет Хартмут, Курт), которые поддерживали большую базу кода, которая была тщательно сконфигурирована с #define
точно #define
с той же проблемой. Простая неправильная орфография, возможно, в файле make, может привести к тонким ошибкам, которые трудно отследить. Их решение: используйте макросы функций! В
#if SOME_COND()
// ...
#endif
компилятор жалуется, если SOME_COND() не определен, в отличие от простого SOME_COND, который будет заменен на 0, если не определено. Мне это нравится, потому что он может использоваться для переноса нескольких значений без загромождения кода с помощью дополнительных #ifdef
s.
Ответ 2
Принятый ответ использования функций-макросов хорош, но если вы хотите сохранить обычные макросы - и по-прежнему использовать значение FOO, если оно определено, и генерировать ошибку, иначе вы могли бы сделать:
#if FOO / defined(FOO)
#else
#endif
Если FOO
не определен, он вызывает целочисленное деление на ноль.
Ответ 3
Как насчет использования препроцессора -Wundef
gcc? Это приведет к появлению предупреждения, которое можно легко переключить на ошибку с -Werror=undef
.
Ответ 4
Я думаю, может решить вашу проблему в простом сложном решении. Я изменяю свой код, как показано ниже, и мой код понимает, что header.h не существует и показывает ошибку для меня.
#if FOO == 1
#pragma message "Hello"
#elif FOO == 2
#pragma message "world!"
#else
throw std::invalid_argument("Header didn't add to project");
#endif
только вам нужно изменить свое начальное значение для Foo. потому что компилятор активирует Foo == 0, когда он не находит FOO, вы не должны использовать значение 0 для вашей конфигурации. вы должны оставить ноль для ситуации отсутствия заголовка. Вместо этого вы должны использовать значения больше нуля (1, 2, 3,...).
Foo == 0 ситуация отсутствия.
Foo == 1 Конфигурация 1.
Foo == 2 Конфигурация 2.
,
,
,