编译器如何处理枚举中的符号常量?

问题描述

如果我们谈论宏,则编译器会在预处理阶段处理宏,但枚举器呢?编译器如何看待它们。例如,请参见以下代码

#include <stdio.h> 
enum day {sunday = 1,monday,tuesday = 5,wednesday,thursday = 10,friday,saturday}; 

int main() 
{ 
    printf("%d %d %d %d %d %d %d",sunday,tuesday,thursday,saturday); 
    return 0; 
} 

在这个特定示例中,我什至没有为枚举数据类型创建任何变量。我只是在enumeration-constants语句中使用printf()。枚举器内部是否与宏类似?在预处理过程中,所有这些符号常量都将被整数常量替换吗?编译器如何精确地处理它们?

解决方法

不,它们不像宏那样工作,而是以某种方式像const变量那样工作。

因此您的代码与此大致相当:

#include <stdio.h> 

const int sunday = 1,monday = 2,tuesday = 5,wednesday = 6,thursday = 10,friday = 11,saturday = 12; 

int main() 
{ 
    printf("%d %d %d %d %d %d %d",sunday,monday,tuesday,wednesday,thursday,friday,saturday); 
    return 0; 
}

在此处查看:https://www.godbolt.org/z/cErv5W

,

枚举器在内部是否与宏类似?

是的,有些不。

所有这些 在此期间,符号常量将替换为整数常量 预处理?

不。除预处理指令,defined运算符和已定义的宏名称之外,预处理器不知道另一个标识符。您可以尝试以下方法:

#include <stdio.h>

#define MACRO_TRUE 1
enum bool_enum { ENUM_FALSE = 0,ENUM_TRUE = 1 };

int main(void) {
#if MACRO_TRUE
    puts("Macro identifiers are known to the preprocessor.");
#else
    puts("Macro identifiers are not known to the preprocessor.");
#endif
#if ENUM_TRUE
    puts("Enum constants are known to the preprocessor.");
#else
    puts("Enum constants are not known to the preprocessor.");
#endif
}

输出应为

Macro identifiers are known to the preprocessor.
Enum constants are not known to the preprocessor.

编译器如何精确地处理它们?

作用域内的枚举常量类似于其他整数常量,例如42,但上述警告除外,即预处理器不会解释它们。例如,它们可以用在整数常量表达式中,这对于各种目的都是必需的,例如case语句中的switch标签。该标准未指定细节,但是大多数编译器将它们与宏类似地对待,因为在可执行文件中没有为它们保留任何存储空间-将源视为将枚举常量替换为其相应的整数值,无论它们出现在表达式中的何处,预处理后。当然,它们不能识别对象,因为它们不是&运算符的可接受的操作数。

这与const限定变量的行为有所区别。这些标识实际对象,而不仅仅是常量。它们可能不会在常量表达式中使用,并且它们确实具有与它们关联的存储(至少在抽象机中),因此可以通过&运算符获取它们的地址。

,

不,枚举在内部不像宏那样工作,枚举是一种数据类型,在编译时会被求值,而预处理器会将宏复制为文本。

从gcc gnu文档中: 宏是已命名的代码片段。每当使用该名称时,它就会被宏的内容替换。有两种宏。它们的主要区别在于使用时的外观。类对象宏在使用时类似于数据对象,类函数宏类似于函数调用。

枚举是C语言的用户定义数据类型。它用于为整数常量分配名称,从而使程序易于阅读和维护。关键字“ enum”用于声明枚举。