gpt4 book ai didi

c - c 预编译器如何处理定义为 (void)0 的宏

转载 作者:太空狗 更新时间:2023-10-29 15:47:36 25 4
gpt4 key购买 nike

我有一些基于编译器标志定义的宏。我正在尝试决定是将宏定义为 (void)0 还是将其未定义并导致编译时错误。

#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) (void)0
#endif

int main(void) {
...
PRINTF("something");
...
}

对比

#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#endif

int main(void) {
...
#ifdef DEBUG
PRINTF("something");
#endif
...
}

我不确定我更喜欢哪种技术。一方面,用#ifdef 包装每个 PRINTF 语句会很丑陋。另一方面,如果我调用了一个在上下文中不起作用的函数,那么在编译时知道它会很好。

我认为决定因素是 (void)0 宏是否会影响可执行文件的大小。

编译代码时,(void)0 会怎样?如果 PRINTF 被定义为 (void)0,这是否意味着可执行文件将包含某种 (void)0 指令,或者它会被完全忽略?

最佳答案

(void) 0;

是一个没有副作用的表达式语句。任何理智的实现都会优化这个语句(还有什么实现可以用这样的语句来做?)。

(void) 0 作为宏定义得到了 C 标准的认可,因为它出现在 (C11) 7.2p1 中用于 assert 宏定义 if NDEBUG 定义:

#define assert(ignore) ((void)0)

注意定义:

#define PRINTF(...) (void)0

代替

#define PRINTF(...)

有优势。在第一种情况下,您有一个表达式(就像一个不返回任何值的函数),因此它可用于例如逗号表达式或条件表达式。

例如:

// Comma expression
printf("test"), PRINTF("Hi Dennis");

// Conditional expression
test-expr ? perror("Hello") : PRINTF("world");

这两个表达式语句只对前面的 PRINTF 定义有效((void) 0)。

关于c - c 预编译器如何处理定义为 (void)0 的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25021081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com