Принудительная ошибка препроцессора с помощью макроса

Есть ли способ заставить макрос препроцессора в C ++ выдавать ошибку? Что я хотел бы сделать, это определить макрос UNKNOWN, Я пишу некоторый код для робота, и я пока не знаю, куда подключается вся электроника. Я хотел бы иметь возможность определить порты в некотором заголовочном файле, например

const int MOTOR_PORT = 1;
const int FAN_PORT = 2;
//etc.

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

const int LED_PORT = UNKNOWN;

В режиме отладки, UNKNOWN было бы просто определено к некоторому произвольному значению, например 0. Однако при компиляции в режиме выпуска я хочу, чтобы он выдавал ошибку, когда UNKNOWN используется, чтобы неназначенные порты не попадали в финальную версию. Я знаю, что могу использовать #error директива, чтобы вызвать ошибку, но я могу сделать что-то подобное в макросе?

Я видел решение, использующее static_assert, но я, к сожалению, не могу использовать C ++ 11 для этой платформы.

0

Решение

поскольку #error не может быть результатом расширения макроса, вы можете убедиться, что макрос расширяется до чего-то, что должно быть диагностировано, например, синтаксическая ошибка.

Например:

#ifdef RELEASE
#define UNKNOWN @Invalid_use_of_UNKNOWN
#else
#define UNKNOWN 0
#endif

const int MOTOR_PORT = 1;
const int FAN_PORT = 2;
const int LED_PORT = UNKNOWN;

int main(void) {
int x = LED_PORT;
}

@ символ не является частью основного набора символов C, поэтому его появление вне комментария, символьной константы или строкового литерала всегда должно приводить к сообщению об ошибке. ($ будет работать, за исключением того, что принимает $ в идентификаторах это общее расширение. ` вероятно, тоже будет работать, но @ выделяется лучше.)

Я определил макрос, поэтому он выдает разумное сообщение об ошибке с помощью gcc:

c.c:9:1: error: stray ‘@’ in program
c.c:9:22: error: ‘Invalid_use_of_UNKNOWN’ undeclared here (not in a function)

и с лязгом:

c.c:9:22: error: expected expression
const int LED_PORT = UNKNOWN;
^
c.c:2:17: note: expanded from:
#define UNKNOWN @Invalid_use_of_UNKNOWN
^
1 error generated.

(Есть _Pragma оператор, соответствующий #pragma директивы. Было бы хорошо, если бы _Error оператор, но нет.)

2

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

Что ж, это не приводит к появлению сообщения об ошибке компилятора, такого как #error, но компилируется при отладке и приводит к сбою в релизе:

#ifdef _DEBUG
#   define UNKNOWN 1
#else
#   define UNKNOWN
#endif
const int port1 = UNKNOWN; // fail in release
1

Вы можете сделать деление на ноль, что приведет к ошибке компиляции:
#define UNKNOWN 0/0

0

sizeof Оператор не может быть применен к неполному типу, поэтому попробуйте это:

// Declared, but not defined anywhere.
struct illegal_use_of_unknown_macro;
#define UNKNOWN (sizeof (illegal_use_of_unknown_macro))
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector