【问题标题】:sizeof operator in #define directives#define 指令中的 sizeof 运算符
【发布时间】:2015-03-04 05:15:57
【问题描述】:

我一直在检查某人的代码,我遇到了这个:

#else //If not in Debug mode

#define LOG_WARNING(str) do { (void)sizeof(str); } while(0)
#define LOG_INFO(str) do { (void)sizeof(str); } while(0)

// ... More #define directives

#endif

显然,do { (void)sizeof(str); } while(0) 是经过精心编写的,因此编译器可以完全忽略该指令。

这是如何工作的?

【问题讨论】:

  • 看起来像是 ( void )str ; 的精巧版本。
  • @LuchianGrigore 这在这里没有任何意义。看来作者过于谨慎了。
  • @LuchianGrigore 我知道do { ... } while(0) 在#define 指令上使用时的工作原理。但是,我不知道为什么添加 (void)sizeof(str) 会使其被编译器忽略
  • @2501 (void)str 能达到同样的效果吗?你知道它是如何工作的吗?我真的很感兴趣

标签: c++ visual-c++ macros c-preprocessor


【解决方案1】:

sizeof 的操作数是未计算的,因此这确保了在运行时没有工作要做。宏只是忽略一个常量值;编译器可以看到它没有任何效果,因此不应该从中生成任何代码。

比什么都不做的好处是编译器仍然检查参数是否是一个有效的表达式;更改代码并仅编译发布时,您不会意外破坏调试版本。

与 cmets 中提到的 (void)str 相比,优势在于它会评估表达式,编译器可能无法消除它,因为它可能会产生副作用。例如:

extern std::string get_message(int code);
LOG_INFO(get_message(code));  // -> (void)get_message(code);

在发布版本中会调用函数并忽略结果,从而影响性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多