标识符的命名空间
由同一标识符指定的不同实体要么具有不同的范围,要么位于不同的命名空间。根据ISO/IEC 9899:2018标准第6.2.3 Name spaces of identifiers节,不同类别的标识符具有单独的命名空间。名称相同、命名空间不同的标识符是有效的;名称相同、命名空间相同的标识符可能会引发冲突。
根据标识符类别,C语言提供了四个独立的命名空间,具体如下:
- 标签名(label names)。
int labelOne; ... goto labelOne; ... labelOne: ...
goto语句中labelOne是标签名,与int labelOne;语句中的labelOne属于不同类别,它们属于不同的命名空间,所以两个labelOne都是有效的。
- 结构、联合和枚举的标记(tag)。
结构、联合、枚举具有相同的命名空间,一个标识符可以用作结构、联合、枚举中任何一个的标记;但不能同时用作其中两个及两个以上的标记。
struct tagName{int money; int year; }; enum tagName{A, B, C, D}; //标记发生冲突。
这里两个tagName标记属于同一命名空间,所以发生了冲突。
- 结构或者联合的成员,每个结构或者联合的成员都有单独的命名空间。
struct car{int year; int money; }; struct computer{int year; int money; };
上述成员名year,money不会发生冲突。
- 所有其它标识符称为普通标识符(ordinary identifiers),包括在普通声明中声明的标识符以及声明为枚举常量的标识符。
int year; enum nationalDay {year, month, day}; //标识符名称发生冲突。
这里两个year标识符命名空间相同,所以发生了冲突。