C 为什么结构声明中的枚举常量而不是成员具有文件作用域?

C 为什么结构声明中的枚举常量而不是成员具有文件作用域?,c,struct,scope,C,Struct,Scope,如果我有 struct example { enum {A, B} letter; int number; } eg; 我可以在文件中的任何其他地方使用A或B,因为{…}后面的示例不构成块,因为括号中可能只包含声明,而不包含语句。因此,enum常量位于任何块之外,根据C标准的6.2.2/4,它们具有文件范围 但是,如果我在main中键入number,我会得到一个未声明的错误。我直观地理解了这一点:我们认为number仅作为example的一个成员存在,需要一个结构实例来访问它。现在,对

如果我有

struct example
{
  enum {A, B} letter;
  int number;
} eg;
我可以在文件中的任何其他地方使用
A
B
,因为
{…}
后面的
示例
不构成块,因为括号中可能只包含声明,而不包含语句。因此,
enum
常量位于任何块之外,根据C标准的6.2.2/4,它们具有文件范围

但是,如果我在
main
中键入
number
,我会得到一个未声明的错误。我直观地理解了这一点:我们认为
number
仅作为
example
的一个成员存在,需要一个结构实例来访问它。现在,对于枚举常量,这种直觉是失败的,因为我不必键入
eg.A
来访问
A
的值,但是如果这种语法遵循C标准,这种直觉是无关紧要的


因此,我的问题是:C标准中的哪些条款规定我必须编写
例如number
才能访问
number

问题不在于范围,而在于名称空间

C 2018 6.2.3 1规定,以下各项有单独的名称空间:

  • 标签(与
    goto
    一起使用)
  • 结构、联合和枚举的标记(标记是
    struct
    union
    enum
    之后的名称,如
    struct foo
  • 结构或联合体的成员(每个结构或联合体的成员都有单独的名称空间);及
  • 所有其他标识符
由于
struct example{…int number;}
声明
number
example
的成员,它位于
struct example
的名称空间中,因此它被识别为
struct example
的成员的唯一位置是
struct example
的成员上下文中,如
x.number
,其中,
x
是类型为
struct example
的表达式

enum
成员名称
A
B
属于上面的“所有其他标识符”类别,因此它们在可能使用普通标识符的任何地方都可以识别


enum
成员名和
struct
成员名都具有文件作用域(假定此声明出现在任何函数之外),稍后在使用它们的文件中写入代码可以看出这一点。例如,如果在源文件的后面,
p
是一个
结构示例*
,那么编译器将接受
p->number
,它将引用
p
number
成员,证明
number
具有文件范围。

问题与其说是范围,不如说是名称空间

C 2018 6.2.3 1规定,以下各项有单独的名称空间:

  • 标签(与
    goto
    一起使用)
  • 结构、联合和枚举的标记(标记是
    struct
    union
    enum
    之后的名称,如
    struct foo
  • 结构或联合体的成员(每个结构或联合体的成员都有单独的名称空间);及
  • 所有其他标识符
由于
struct example{…int number;}
声明
number
example
的成员,它位于
struct example
的名称空间中,因此它被识别为
struct example
的成员的唯一位置是
struct example
的成员上下文中,如
x.number
,其中,
x
是类型为
struct example
的表达式

enum
成员名称
A
B
属于上面的“所有其他标识符”类别,因此它们在可能使用普通标识符的任何地方都可以识别


enum
成员名和
struct
成员名都具有文件作用域(假定此声明出现在任何函数之外),稍后在使用它们的文件中写入代码可以看出这一点。例如,如果在源文件的后面,
p
是一个
struct example*
,那么编译器将接受
p->number
,它将引用
p
number
成员,证明
number
具有文件范围。

我想你可以把它翻过来-标准中没有任何地方定义
number
在其他上下文中的任何含义,除了
例如number
(有
offsetof
等例外).6.2怎么样。3@user3386109这是我的第一个怀疑,但它只是说,如果“一个特定标识符的多个声明是可见的……”。在该示例中,只有一个
number
声明(该声明应在
main
中可见,因为它位于文件范围内)。我不确定6.2.3是否适用。@NateEldredge但我不能将这一点与
int number
是具有文件范围的
number
的声明相协调。我不知道如何从子句中“推导”出
enum
int number
的差异。我也注意到了这一点,但我认为第二句中的“因此”一词优先于第一句中的“如果”。换句话说,“如果”条款只适用于第一句话的后半部分(逗号后)。我想你可以把它翻过来——标准中没有任何地方定义
number
以外的上下文中的任何含义,例如number
(有
offsetof
等例外).6.2怎么样。3@user3386109这是我的第一个怀疑,但它只是说,如果“一个特定标识符的多个声明是可见的……”。在该示例中,只有一个
number
声明(该声明应在
main
中可见,因为它位于文件范围内)。我不确定6.2.3是否适用。@NateEldredge,但我不能将其与t的事实相协调