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的成员