为什么编译器不给出冲突错误?
Why doesn't the compiler give a conflicting error?
在下面的代码中,我声明了一个与结构名称同名的结构成员变量。
struct st
{
int st;
};
int main()
{
struct st t;
t.st = 7;
return 0;
}
我想知道,它在 GCC 编译器上运行良好,不会出现冲突错误。
所以,
- 编译器如何知道结构名和变量名?
- 编译器内部使用什么机制?
结构类型的名称是struct st
。不只是st
,所以完全没有冲突。
是的,有效。结构标签和结构成员在不同的命名空间中。
C11, 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).
在下面的代码中,我声明了一个与结构名称同名的结构成员变量。
struct st
{
int st;
};
int main()
{
struct st t;
t.st = 7;
return 0;
}
我想知道,它在 GCC 编译器上运行良好,不会出现冲突错误。
所以,
- 编译器如何知道结构名和变量名?
- 编译器内部使用什么机制?
结构类型的名称是struct st
。不只是st
,所以完全没有冲突。
是的,有效。结构标签和结构成员在不同的命名空间中。
C11, 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).