Есть ли способ заставить макрос препроцессора в 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 для этой платформы.
поскольку #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
оператор, но нет.)
Что ж, это не приводит к появлению сообщения об ошибке компилятора, такого как #error, но компилируется при отладке и приводит к сбою в релизе:
#ifdef _DEBUG
# define UNKNOWN 1
#else
# define UNKNOWN
#endif
const int port1 = UNKNOWN; // fail in release
Вы можете сделать деление на ноль, что приведет к ошибке компиляции:
#define UNKNOWN 0/0
sizeof
Оператор не может быть применен к неполному типу, поэтому попробуйте это:
// Declared, but not defined anywhere.
struct illegal_use_of_unknown_macro;
#define UNKNOWN (sizeof (illegal_use_of_unknown_macro))