为什么枚举常量而不是结构声明中的成员具有文件范围?

Why do enum constants but not members in struct declarations have file scope?

如果我有

struct example
{
  enum {A, B} letter;
  int number;
} eg;

我可以在文件的其他任何地方使用 AB,因为 example 之后的 {...} 不构成一个块,因为括号可能只包含声明,而不是语句。因此,enum 常量位于任何块之外,并且根据 C 标准的 6.2.2/4,它们具有文件范围。

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

因此,我的问题是:从C标准中的哪些条款可以看出我必须写eg.number才能访问number

问题不在于名称 space 的范围。

C 2018 6.2.3 1 表示有单独的名称 spaces for:

  • 标签(与goto一起使用);
  • 结构、联合、枚举的标签(标签是structunionenum之后的名字,如struct foo);
  • 结构或联合的成员(每个结构或联合的成员都有一个单独的名称 space);和
  • 所有其他标识符。

由于struct example { … int number; }number声明为example的成员,它在struct example的名称space中,所以唯一的地方是被识别为 struct example 的成员是在 struct example 的成员的上下文中,如 x.number,其中 x 是类型 struct example 的表达式。

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

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