【问题标题】:C macros, what's the meaning of ((void)0)?C宏,((void)0)是什么意思?
【发布时间】:2020-04-11 13:31:06
【问题描述】:

给定以下根据 C99 标准编写的代码:

#define LOW 1 
#define MEDIUM 2 
#define HIGH 3

#define LOGGING_LEVEL HIGH

#if LOGGING_LEVEL >= MEDIUM
#define LOG_MEDIUM(message) printf(message) 
#else
#define LOG_MEDIUM(message) ((void)0) 
#endif

void load_configuration() { 
//...
LOG_MEDIUM("Configuration loaded\n"); 
}

((void)0) 的目的是什么,我在网上搜索了很多,但没有找到任何相关信息。

另外,为什么我们在使用printf(message) 之后不写;

【问题讨论】:

  • 那是没有操作。
  • 它只是创建了一个空值结果。 0 只是一个虚拟值,因为转换需要应用于表达式。 void 强制转换丢弃该值。您可以将整个事物视为一个 void 值的常量表达式。
  • @TomKarzes 好的,但为什么我们首先需要一个空值常量表达式?
  • 另外,他们将分号; 留在宏之外的原因是用户可以添加它。否则,如果他们有分号并且用户添加了第二个,它将成为一系列语句并且可能是语法问题,例如if (c) MACRO; else x; 将扩展为 if (c) expr;; else x;,这将是由于双分号 ;; 而导致的语法错误。
  • @Chris1998ch 哦,我认为 Thomas Dickey 对void 演员阵容有一个很好的解释。将其设为无效值可避免对无效语句的警告。我确定这就是他们使用((void) 0) 而不仅仅是(0) 的原因。

标签: c macros c99 void


【解决方案1】:

主要思想是在不符合条件的情况下排除所有LOG_MEDIUM。 编译后,这些调用不会影响功能。

【讨论】:

    【解决方案2】:

    void-cast 修复了编译器警告。这是一个类似的测试用例:

    int main(void)
    {
            0; // generates "foo.c:3:2: warning: statement with no effect"
            (void)0;
            return 0;
    }
    

    并且(使用script 添加 gcc 的警告标志)您会看到没有强制转换的行的警告:

    $ gcc-stricter -c foo.c
    foo.c: In function ‘main’:
    foo.c:3:2: warning: statement with no effect [-Wunused-value]
      0;
      ^
    

    额外的括号和缺少分号允许宏的结果与printf 互换使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-08
      • 2011-11-19
      • 1970-01-01
      • 2016-12-03
      • 2013-03-09
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多