当前位置: C语言 -- 基础 -- 标识符的命名空间

标识符的命名空间

由同名标识符指定的不同实体要么具有不同的作用域,要么位于不同的命名空间(name spaces)。命名空间用于组织管理标识符的名称,避免标识符的名称发生冲突。同一命名空间内所有标识符名称都是唯一的。名称相同、命名空间不同的标识符是有效的;名称相同、命名空间相同的标识符可能会引发名称冲突。


对于不同类别的标识符,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发生冲突。

这里两个tagName标记属于同一命名空间,因此发生了名称冲突。


三、结构或者联合的成员

每个结构或者联合的成员都有单独的命名空间。

struct car{int year;
           int money;
           };

struct computer{int year;
                int money;
                };

上述成员名yearmoney不会发生冲突。


四、标准属性(standard attributes)和属性前缀(attribute prefixes)

ISO/IEC 9899:2024标准增加了属性相关的内容。属性指定了各种源构造(例如:类型、对象、标识符、块。)的附加信息。属性使用属性标记(attribute token)标识。属性标记包括标准属性和属性前缀标记(attribute prefixed token)。标准属性是ISO/IEC 9899:2024标准指定的属性;属性前缀标记是特定实现支持的属性。


ISO/IEC 9899:2024标准支持的标准属性如下表所示:

标准属性
属性标记 属性
deprecated [[deprecated]]
fallthrough [[fallthrough]]
maybe_unused [[maybe_unused]]
nodiscard [[nodiscard]]
noreturn [[noreturn]]
_Noreturn [[_Noreturn]]
reproducible [[reproducible]]
unsequenced [[unsequenced]]

属性前缀标记语法格式如下所示:

attribute-prefix :: identifier

其中attribute-prefix是属性前缀,::是域解析符,identifier是尾随标识符,例如:gnu::const


[[gnu::const]] [[nodiscard]] int func(int);

其中[[gnu::const]]GCC编译器支持的属性;[[nodiscard]]是标准属性。


五、属性前缀标记中的尾随标识符(the trailing identifier in an attribute prefixed token)

每个属性前缀都有一个单独的命名空间,用于其引用的实现定义的属性,通过属性前缀和尾随标识符可以消除属性间的歧义,例如:[[deprecated]][[gnu::deprecated]],前者是标准属性,后者是实现定义的属性。


六、普通标识符(ordinary identifiers)

所有其它标识符称为普通标识符,包括在普通声明中声明的标识符以及声明为枚举成员的标识符。

int year;

enum nationalDay {year, month, day};    //标识符year名称发生冲突。

这里两个标识符year命名空间相同,因此发生了名称冲突。



主要参考资料:

1、ISO/IEC 9899:2024

2、ISO/IEC 9899:2018

3、cppreference.com : Lookup and name spaces

4、learn.microsoft.com : Name Spaces

5、en.cppreference.com : Attribute specifier sequence

6、gcc.gnu.org : Attribute Syntax