我试图更好地理解#define处理并查看一个asssert.h文件作为一个简单的例子。代码是:
# define assert(EX) (void)((EX) || (__assert (#EX, __FILE__, __LINE__),0))
我对OR表达式感到困惑。我假设这一行说如果表达式为true,则不执行任何操作,如果为false,则调用__assert函数。但是预处理器如何处理该行以及OR在何处确定assert的定义?为什么(虚空)演员?
感谢您的任何澄清。
答案 0 :(得分:4)
请注意,在这种情况下,预处理器不评估任何内容,它只是 使用传递的表达式对宏进行文本替换。
我们假设你有变量int x = 2;
执行assert(x == 3)
时,预处理器会将其扩展为
(void)((x == 3) || __assert("x == 3", "test.c", 13),0);
由于x
为2,x==3
评估为false,右侧必须为。text.c
评估(见Short-Circuit evaluation)。当右边
进行评估(假设源是__assert("x == 3", "text.c", 13),0
,你在第13行做了那个)
__assert
((x == 3) || __assert("x == 3", "test.c", 13),0);
将在text.c:13 上打印 x == 3失败的内容。使用逗号运算符
所以继续评估下一个表达式并返回该值作为结果
整个表达式(见comma operator),在本例中为0,所以是
__assert
为0. __assert
可能是一个函数或另一个宏,但是因为你没有
显示了x
的定义,我将其视为一种功能。
如果x == 3
为3,那么||
会评估为真,而右侧则不会
完全评估,因为(void)
如果任何一方为真,则评估为真,如果
左侧已经是真的,那么就没有必要评估右侧了
(再看看Short-Circuit evaluation)。
当您使用所有警告进行编译时,{{1}}可以使编译器静音, 编译器可能会警告您没有使用变量。