C 枚举范围
如果我有如下枚举:C 枚举范围,c,enums,C,Enums,如果我有如下枚举: enum EnumA { stuffA = 0 }; enum enumAA { stuffA = 1 }; 当您参考stuffA时,这里会发生什么?我想你会像在Java中那样引用它们,比如EnumA.stuffA和EnumB.stuffA,但在C中似乎不是这样。enums不要引入新的范围 在您的示例中,由于stuffA名称冲突,第二个enum无法编译 为避免名称冲突,通常为enum的元素指定一个公共前缀。不同的枚举将使用不同的前缀: enum EnumA {
enum EnumA
{
stuffA = 0
};
enum enumAA
{
stuffA = 1
};
当您参考
stuffA
时,这里会发生什么?我想你会像在Java中那样引用它们,比如EnumA.stuffA
和EnumB.stuffA
,但在C中似乎不是这样。enums
不要引入新的范围
在您的示例中,由于stuffA
名称冲突,第二个enum
无法编译
为避免名称冲突,通常为enum
的元素指定一个公共前缀。不同的枚举将使用不同的前缀:
enum EnumA
{
EA_stuffA = 0
};
enum EnumAA
{
EAA_stuffA = 1
};
枚举
不引入新范围
在您的示例中,由于stuffA
名称冲突,第二个enum
无法编译
为避免名称冲突,通常为enum
的元素指定一个公共前缀。不同的枚举将使用不同的前缀:
enum EnumA
{
EA_stuffA = 0
};
enum EnumAA
{
EAA_stuffA = 1
};
枚举常量位于全局名称空间(更准确地说,是普通标识符名称空间,与标签、标记和结构/联合成员名称空间形成对比),因此在第二个
stuffA
中会出现编译错误
在一个转换单元中,不能对同一枚举名称使用两个不同的值(也不能指定两次相同的值)。枚举常量位于全局名称空间(更准确地说,是普通标识符名称空间,与标签、标记和结构/联合成员名称空间相比),因此,在第二个
stuffA
上出现编译错误
不能在一个翻译单元中对同一枚举名称使用两个不同的值(也不能对同一个值指定两次)。如前所述,这不会编译,因为stuffA定义了两次。枚举仅引用枚举值(即“stuffA”而不是EnumA.stuffA)。您甚至可以在非枚举的类型(如整数)上使用它们。枚举有时与int一起使用,类似于定义常量的方式。如前所述,这不会编译,因为stuffA定义了两次。枚举仅引用枚举值(即“stuffA”而不是EnumA.stuffA)。您甚至可以在非枚举的类型(如整数)上使用它们。枚举有时与int一起使用,类似于定义常量的方式。因为其他枚举常量在定义它们的实际范围内必须是唯一的。但与其他标识符一样,可以在另一个范围内重新定义它们。例如
enum EnumA
{
stuffA = 0
};
void func(void) {
enum enumAA
{
stuffA = 1
};
// do something
}
好的。但是,在不同范围内的这种重新定义通常是不受欢迎的,并且应该有很好的文档记录,否则您将很快失去自己和他人。正如其他人所说,枚举常量在定义它们的实际范围内必须是唯一的。但与其他标识符一样,可以在另一个范围内重新定义它们。例如
enum EnumA
{
stuffA = 0
};
void func(void) {
enum enumAA
{
stuffA = 1
};
// do something
}
好的。但是在不同的范围内进行这样的重新定义通常是不受欢迎的,并且应该有很好的文档记录,否则您将很快失去自己和他人。根据您声明这些枚举的位置,您还可以使用namespace关键字声明新的范围 注意:我不建议这样做,我只是指出这是可能的。 相反,最好使用其他示例中提到的前缀
namespace EnumA
{
enum EnumA_e
{
stuffA = 0
};
};
namespace EnumAA
{
enum enumAA_e
{
stuffA = 1
};
};
根据声明这些枚举的位置,还可以使用namespace关键字声明新的作用域 注意:我不建议这样做,我只是指出这是可能的。 相反,最好使用其他示例中提到的前缀
namespace EnumA
{
enum EnumA_e
{
stuffA = 0
};
};
namespace EnumAA
{
enum enumAA_e
{
stuffA = 1
};
};
这个答案显示了C 2018的规则如何阻止相同的标识符被用作两个不同枚举的成员。这是一种语言律师观点,旨在说明该要求是如何从标准语言中产生的 6.2.3“标识符的名称空间”告诉我们: 如果一个特定标识符的多个声明在翻译单元中的任何一点都可见,那么语法上下文将消除引用不同实体的用法的歧义。因此,不同类别的标识符有单独的名称空间,如下所示: -所有其他标识符,称为普通标识符(在普通声明器中声明或作为枚举常量声明) 因此,所有枚举数常量和普通声明符都存在于一个名称空间中。(上面省略的名称空间用于标签[用于
goto
语句];结构、联合和枚举的标记[在struct
之后的名称,如在struct foo
中];以及结构或联合的成员[每个成员都有自己的名称空间])
6.7“声明”在第5段中告诉我们:
标识符的定义是该标识符的声明:
对于枚举常量,是标识符的(唯一)声明
因此,该标准指出枚举常量只有一个定义。此外,6.2.1“标识符范围”在第1段中告诉我们:
标识符可以表示对象;函数;标记结构、联合或枚举的标记或成员;typedef名称;标签名称;宏名称;或宏参数。同一标识符可以表示程序中不同点上的不同实体。枚举的成员称为枚举常量
请注意,这表明如果foo
标识枚举常量,则它标识枚举的一个成员它是特定枚举的一个特定成员。它不能同时识别枚举a
的成员和枚举B
的成员。因此,如果我们有代码:
enum A { foo = 1 };
enum B { foo = 1 };
在第二次出现foo
时,它是enum A
中foo
的标识符,因此它不能是enu的成员