为什么 typedef 的名称可以用作结构成员的名称?
Why can typedef'd names be used as the names of struct members?
我刚刚发现 gcc
和 clang
都接受以下代码:
typedef int blah;
struct s { char blah; };
但是,他们拒绝这样做,因为类型名称被用作标识符:
typedef int blah;
char blah;
这是否意味着 typedef 的名称在结构定义中不可见?不,因为这在 gcc 和 clang 中都有效:
typedef int blah;
struct s { blah blah; }
我正在查看 C99 标准,但找不到任何内容来阐明为什么 typedef 的名称可以用作结构成员的名称,但不能用作同一范围内的变量的名称。
有人可以解释这是为什么吗?如果能参考任何适用的标准,我们将不胜感激。
取自此处:https://www.spinellis.gr/cscout/doc/name.html
C 有 4 个不同的命名空间。这些不是来自 C++ 的名称空间,它们可以使用关键字 namespace
访问。相反,这些是符号的单独区域:
struct/union/enum
的标签
struct/union的成员(实际上每个struct/union都分配了一个单独的命名空间)
标签
普通标识符(在 C 标准中称为对象)
结构成员和普通变量在不同的名字space中。这就是为什么有两个具有相同标识符名称的普通变量会失败,而如果在结构成员中使用相同的标识符名称并且普通变量是好的。
C 标准定义了不同的名称spaces:
6.2.3 Name spaces of identifiers
If more than one declaration of a particular identifier is visible at
any point in a translation unit, the syntactic context disambiguates
uses that refer to different entities. Thus, there are separate name
spaces for various categories of identifiers, as follows:
- label names (disambiguated by the syntax of the label declaration and use);
- the tags of structures, unions, and enumerations (disambiguated by following any32) of the keywords struct, union, or enum);
- the members of structures or unions; each structure or union has a separate name space for its members (disambiguated by the type of the
expression used to access the member via the . or -> operator);
- all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).
(最后两项直接解决这个问题)
是的,typedef
ed 标识符与普通标识符共享名称 space。 6.7.8 Type definitions:
[...] A typedef name shares the same name space as other identifiers declared in ordinary declarators.
我刚刚发现 gcc
和 clang
都接受以下代码:
typedef int blah;
struct s { char blah; };
但是,他们拒绝这样做,因为类型名称被用作标识符:
typedef int blah;
char blah;
这是否意味着 typedef 的名称在结构定义中不可见?不,因为这在 gcc 和 clang 中都有效:
typedef int blah;
struct s { blah blah; }
我正在查看 C99 标准,但找不到任何内容来阐明为什么 typedef 的名称可以用作结构成员的名称,但不能用作同一范围内的变量的名称。
有人可以解释这是为什么吗?如果能参考任何适用的标准,我们将不胜感激。
取自此处:https://www.spinellis.gr/cscout/doc/name.html
C 有 4 个不同的命名空间。这些不是来自 C++ 的名称空间,它们可以使用关键字 namespace
访问。相反,这些是符号的单独区域:
struct/union/enum
的标签
struct/union的成员(实际上每个struct/union都分配了一个单独的命名空间)
标签
普通标识符(在 C 标准中称为对象)
结构成员和普通变量在不同的名字space中。这就是为什么有两个具有相同标识符名称的普通变量会失败,而如果在结构成员中使用相同的标识符名称并且普通变量是好的。
C 标准定义了不同的名称spaces:
6.2.3 Name spaces of identifiers
If more than one declaration of a particular identifier is visible at any point in a translation unit, the syntactic context disambiguates uses that refer to different entities. Thus, there are separate name spaces for various categories of identifiers, as follows:
- label names (disambiguated by the syntax of the label declaration and use);
- the tags of structures, unions, and enumerations (disambiguated by following any32) of the keywords struct, union, or enum);
- the members of structures or unions; each structure or union has a separate name space for its members (disambiguated by the type of the expression used to access the member via the . or -> operator);
- all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).
(最后两项直接解决这个问题)
是的,typedef
ed 标识符与普通标识符共享名称 space。 6.7.8 Type definitions:
[...] A typedef name shares the same name space as other identifiers declared in ordinary declarators.