#define 在 assert.h 例子中
#define in assert.h example
我试图更好地理解#define 处理并将 asssert.h 文件作为一个简单示例。代码是:
# define assert(EX) (void)((EX) || (__assert (#EX, __FILE__, __LINE__),0))
我对 OR 表达式感到困惑。我假设这一行是说如果表达式为真,则什么都不做,如果为假,则调用 __assert 函数。但是预处理器如何处理该行以及OR在哪里确定断言的定义?为什么 (void) 强制转换?
感谢您的澄清。
请注意,在这种情况下,预处理器不会评估任何东西,它只是
使用传递的表达式对宏进行文本替换。
假设您有变量 int x = 2;
当您执行 assert(x == 3)
时,预处理器会将其扩展为
(void)((x == 3) || __assert("x == 3", "test.c", 13),0);
因为 x
是 2,所以 x==3
被评估为 false 并且右边必须是
评估(参见 Short-Circuit evaluation)。当右侧
被评估(假设来源是 text.c
而你在第 13 行做了)
__assert("x == 3", "text.c", 13),0
__assert
会打印类似 x==3 failed on text.c:13 的内容。使用逗号运算符
所以继续评估下一个表达式和 return 该值作为结果
整个表达式的(参见 comma operator),在本例中为 0,因此
的结果
((x == 3) || __assert("x == 3", "test.c", 13),0);
是 0。__assert
可能是一个函数或另一个宏,但是因为你还没有
显示了 __assert
的定义,我将其视为一个函数。
但是,如果 x
为 3,则 x == 3
的计算结果为真,而右侧则不会
完全评估,因为 ||
如果任何一方为真,则评估为真,如果
左侧已经为真,则无需评估右侧
(再次参见 Short-Circuit evaluation)。
(void)
是为了让编译器在编译时带有所有警告时静音,
编译器可能会警告您未使用的变量。
我试图更好地理解#define 处理并将 asssert.h 文件作为一个简单示例。代码是:
# define assert(EX) (void)((EX) || (__assert (#EX, __FILE__, __LINE__),0))
我对 OR 表达式感到困惑。我假设这一行是说如果表达式为真,则什么都不做,如果为假,则调用 __assert 函数。但是预处理器如何处理该行以及OR在哪里确定断言的定义?为什么 (void) 强制转换?
感谢您的澄清。
请注意,在这种情况下,预处理器不会评估任何东西,它只是 使用传递的表达式对宏进行文本替换。
假设您有变量 int x = 2;
当您执行 assert(x == 3)
时,预处理器会将其扩展为
(void)((x == 3) || __assert("x == 3", "test.c", 13),0);
因为 x
是 2,所以 x==3
被评估为 false 并且右边必须是
评估(参见 Short-Circuit evaluation)。当右侧
被评估(假设来源是 text.c
而你在第 13 行做了)
__assert("x == 3", "text.c", 13),0
__assert
会打印类似 x==3 failed on text.c:13 的内容。使用逗号运算符
所以继续评估下一个表达式和 return 该值作为结果
整个表达式的(参见 comma operator),在本例中为 0,因此
((x == 3) || __assert("x == 3", "test.c", 13),0);
是 0。__assert
可能是一个函数或另一个宏,但是因为你还没有
显示了 __assert
的定义,我将其视为一个函数。
但是,如果 x
为 3,则 x == 3
的计算结果为真,而右侧则不会
完全评估,因为 ||
如果任何一方为真,则评估为真,如果
左侧已经为真,则无需评估右侧
(再次参见 Short-Circuit evaluation)。
(void)
是为了让编译器在编译时带有所有警告时静音,
编译器可能会警告您未使用的变量。