为什么枚举常量而不是结构声明中的成员具有文件范围?
Why do enum constants but not members in struct declarations have file scope?
如果我有
struct example
{
enum {A, B} letter;
int number;
} eg;
我可以在文件的其他任何地方使用 A
或 B
,因为 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
一起使用);
- 结构、联合、枚举的标签(标签是
struct
、union
、enum
之后的名字,如struct foo
);
- 结构或联合的成员(每个结构或联合的成员都有一个单独的名称 space);和
- 所有其他标识符。
由于struct example { … int number; }
将number
声明为example
的成员,它在struct example
的名称space中,所以唯一的地方是被识别为 struct example
的成员是在 struct example
的成员的上下文中,如 x.number
,其中 x
是类型 struct example
的表达式。
enum
成员名称 A
和 B
属于上面的“所有其他标识符”类别,因此在任何可能使用普通标识符的地方都可以识别它们。
enum
成员名称和 struct
成员名称都具有文件范围(假设此声明出现在任何函数之外),稍后在使用的文件中编写代码可以看出任何一位。例如,如果稍后在源文件中,p
是一个 struct example *
,那么编译器将接受 p->number
,并且它会引用 number
的成员 p
,表明 number
具有文件范围。
如果我有
struct example
{
enum {A, B} letter;
int number;
} eg;
我可以在文件的其他任何地方使用 A
或 B
,因为 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
一起使用); - 结构、联合、枚举的标签(标签是
struct
、union
、enum
之后的名字,如struct foo
); - 结构或联合的成员(每个结构或联合的成员都有一个单独的名称 space);和
- 所有其他标识符。
由于struct example { … int number; }
将number
声明为example
的成员,它在struct example
的名称space中,所以唯一的地方是被识别为 struct example
的成员是在 struct example
的成员的上下文中,如 x.number
,其中 x
是类型 struct example
的表达式。
enum
成员名称 A
和 B
属于上面的“所有其他标识符”类别,因此在任何可能使用普通标识符的地方都可以识别它们。
enum
成员名称和 struct
成员名称都具有文件范围(假设此声明出现在任何函数之外),稍后在使用的文件中编写代码可以看出任何一位。例如,如果稍后在源文件中,p
是一个 struct example *
,那么编译器将接受 p->number
,并且它会引用 number
的成员 p
,表明 number
具有文件范围。