为什么可以使用 typedef 的名称作为结构成员的名称?

Ale*_*x D 7 c struct scope typedef

我刚刚发现gccclang接受以下代码:

typedef int blah;
struct s { char blah; };
Run Code Online (Sandbox Code Playgroud)

但是,他们拒绝这样做,因为类型名称被用作标识符:

typedef int blah;
char blah;
Run Code Online (Sandbox Code Playgroud)

这是否意味着 typedef 的名称在结构定义中不可见?不,因为这在 gcc 和 clang 中都有效:

typedef int blah;
struct s { blah blah; }
Run Code Online (Sandbox Code Playgroud)

我正在查看 C99 标准,但找不到任何说明为什么 typedef 名称可以用作结构成员的名称,但不能用作同一范围内变量的名称的任何内容。

有人可以解释为什么会这样吗?参考任何适用的标准将不胜感激。

P.P*_*.P. 9

结构体成员和普通变量在不同的命名空间中。这就是为什么有两个具有相同标识符名称的普通变量会失败,而如果在 struct 成员中使用相同的标识符名称并且普通变量很好。

C 标准定义了不同的命名空间:

6.2.3 标识符的命名空间

如果在翻译单元中的任何一点都可以看到多个特定标识符的声明,则句法上下文会消除引用不同实体的用法的歧义。因此,各种类别的标识符都有单独的名称空间,如下所示:

  • 标签名称(通过标签声明和使用的语法消除歧义);
  • 关键字 struct、union 或 enum的结构、联合和枚举的标签(通过跟随任何32 个来消除歧义);
  • 结构或工会的成员;每个结构或联合都有一个单独的名称空间用于其成员(通过用于通过 . 或 -> 运算符访问成员的表达式类型来消除歧义);
  • 所有其他标识符,称为普通标识符(在普通声明符中声明或作为枚举常量声明)。

(最后两个项目符号直接解决了这个问题)

是的,typedef'ed 标识符与普通标识符共享名称空间。6.7.8 类型定义

[...] typedef 名称与普通声明符中声明的其他标识符共享相同的名称空间。