使用宏强制预处理程序错误

时间:2014-01-10 22:19:04

标签: c++ debugging macros c-preprocessor

有没有办法可以强制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。

4 个答案:

答案 0 :(得分:2)

由于#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)

和clang:

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运算符会很好,但是没有。)

答案 1 :(得分:1)

好吧,这不会产生像#error这样的编译器错误消息,但会在调试中编译并在发布时失败:

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

答案 2 :(得分:0)

你可以将除法归零,这将引发编译错误: #define UNKNOWN 0/0

答案 3 :(得分:0)

sizeof运算符无法应用于不完整类型,请尝试以下操作:

// Declared, but not defined anywhere.
struct illegal_use_of_unknown_macro;
#define UNKNOWN (sizeof (illegal_use_of_unknown_macro))