【问题标题】:Macro inside enum in CC中枚举内部的宏
【发布时间】:2020-12-28 17:24:14
【问题描述】:

在 C 中尝试在枚举中编写宏时。 有时我们必须在宏定义上面写宏的名字,为什么?

#include <stdio.h>

enum month {    

        MSD //If I remove or comment this line, code does not work, why?
        #define MSD 7
};

void main() {
        printf("%d\n", MSD);
}

如果我们删除第 5 行代码,即“MSD”。我们得到错误 空枚举无效为什么会这样,谁能解释一下?

【问题讨论】:

  • 当第 5 行不存在时,您认为 应该 发生什么?
  • 记住预处理器的工作原理:宏在代码传递给编译器之前被扩展。想想编译器实际上看到了什么。没有“宏变量”之类的东西,也不是“声明”。
  • 打开,并阅读,你的编译器诊断。

标签: c enums nested macros c-preprocessor


【解决方案1】:

宏和枚举是不同的东西。最重要的是,宏仅在编译时存在,因此预处理器会将以下代码中的所有MSD 实例替换为7,就像您在编辑器中进行了查找和替换一样。另一方面,枚举存在于运行时,通常是映射到符号的数值。

现在,使用您的代码,printf("%d\n", MSD); 中的 MSD 在编译时被 7 替换,因此从未实际使用枚举。如果删除第 5 行代码,编译器会看到一个空枚举,因为 #define MSD 7 宏被预处理器过滤掉,枚举中没有其他内容。

【讨论】:

    【解决方案2】:

    如果意图是定义一个枚举。我们可以定义如下。 (我们可以以#define 枚举的形式定义 MSD,其中任何一个都需要在代码中为值 7 使用“MSD”)

        #include <stdio.h>
    
        enum month {
                MSD = 7,
                TST = 1 // added just for ref
        };
        // in linux requires int main() { <code> return 0;}
        void main() {
                printf("enum MSD == %d\n", MSD);
        }
    

    【讨论】:

    • 不,先生,其目的不是定义枚举。我正在阅读头文件的源代码,并想知道他们为什么要那样编写宏,我已经在其中发布了
    【解决方案3】:

    我正在阅读头文件的源代码,并想知道他们为什么要这样编写宏,我已经在其中发布了

    我认为您可能误读了一个头文件,该头文件正在做这件稍微不同的事情:

    enum thing_enum {
        THING_ONE = 1,
    #define THING_ONE THING_ONE
        THING_TWO,
    #define THING_TWO THING_TWO
        // etc
    };
    

    这和写一个普通的枚举声明是一样的

    enum thing_enum {
        THING_ONE = 1,
        THING_TWO,
        // etc
    };
    

    然后,还将每个枚举器定义为扩展至自身的宏:

    #define THING_ONE THING_ONE
    #define THING_TWO THING_TWO
    // etc
    

    这样写,应该更清楚为什么在注释掉代码中的“MSD”行时会出现错误:#define 对枚举的定义没有任何贡献,所以你有一个枚举没有值,这是语言不允许的。

    头文件做了这个看起来很奇怪的事情,因为它使每个THING_ 常量both 是一个宏和一个枚举值,这意味着您可以使用enum 的所有功能来设置它们值(例如,在我的示例中,THING_TWO 等于 2,而我不必明确说明)并且名称将对调试器可见,但仍然可以使用 #ifdef 检查特定常量的存在.

    缺点是常量集定义的长度加倍,不能使每个常量的类型为int以外的任何类型,并且不能在#if表达式中使用常量(除了作为defined的参数)。

    (注意:扩展为自身的宏不会将预处理器置于无限循环中。THING_ONE 被替换为THING_ONE once 然后预处理器转到下一个令牌。)

    【讨论】:

      【解决方案4】:

      MSD与上面声明#define MSD 7无关,错误原因是enum{ };不能为空。

      如果枚举为空,则会出现以下错误。

      main.c:12:1: 错误:空枚举无效 };

      尝试在那里声明另一个enum 值而不是MSD,它将如下所示。

      #defines 是文本替换,它们不需要任何声明,只需要定义。

      #include <stdio.h>
      
      enum month {    
              x = 0
              //MSD //If I remove or comment this variable declaration, code does not work, why?
              #define MSD 7
      };
      
      void main() {
              printf("%d\n", MSD);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-26
        • 2018-01-22
        • 2013-09-19
        • 2017-08-16
        • 1970-01-01
        • 2016-08-15
        • 1970-01-01
        相关资源
        最近更新 更多