强制使用宏的预处理器错误

Forcing preprocessor error with macro

本文关键字:预处理 处理器 错误      更新时间:2023-10-16

有没有办法强制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))