标识符的命名空间如何在 C 中工作?

Rob*_*rtS 0 c entity namespaces identifier

我知道命名空间在 C++ 中是如何工作的,但我对它们在 C 中的工作方式有点困惑。所以,我对 C 中的命名空间做了一些研究。

首先,ISO/IEC 9899:2018 (C18) 第 6.2.3 节中的相应部分:

6.2.3 标识符的命名空间

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

— 标签名称(通过标签声明和使用的语法消除歧义);— 结构、联合和枚举的标签(通过关键字 struct、union 或 enum 的 any(32) 消除歧义);

——结构或工会的成员;每个结构或联合都有一个单独的名称空间用于其成员(通过用于通过 . 或 -> 运算符访问成员的表达式类型消除歧义);

— 所有其他标识符,称为普通标识符(在普通声明符中声明或作为枚举常量声明)。


32) 标签只有一个命名空间,尽管三个是可能的。

所以这让我对 C 中的术语有了更多的理解,并且似乎通常与 C++ 具有相同的目的。但不幸的是,标准中没有进一步说明名称空间在 C 中的工作方式。

显然,它与共享相同标识符的实体之间的区别有关,并且与 C++ 不同,我们在其中声明命名空间,例如:

namespace ctrl1 
{ 
    int max = 245; 
} 
Run Code Online (Sandbox Code Playgroud)

并使用命名空间,例如:

using namespace ctrl1;
Run Code Online (Sandbox Code Playgroud)

或者

int a = ctrl1::max;
Run Code Online (Sandbox Code Playgroud)

在 C 中,如果使用了相应的标识符,编译器能够自动消除某个对象的某种用法的歧义。如果我错了纠正我。

这是如何运作的?编译器如何知道他是否应该在 C 中使用一个实体而不是另一个实体?


我已经阅读了 c++ 和 c 中的命名空间但问题更侧重于 C++ 并侧重于特定示例的处理。

我还阅读了C中的命名空间,其中问题的目的更侧重于一个特定的例子,这里是enum类型。


我的问题是:

  • 命名空间如何在 C 中工作?

Joh*_*ger 8

在 C 中,如果使用了相应的标识符,编译器能够自动消除某个对象的某种用法的歧义。如果我错了纠正我。

这是如何运作的?编译器如何知道他是否应该在 C 中使用一个实体而不是另一个实体?

该标准的摘录已经解决了这个问题(强调):

— 标签名称(通过标签声明和使用的语法消除歧义);

标签声明的形式是标识符后跟一个冒号,后面必须跟一个语句:

a_label:
do_something;
Run Code Online (Sandbox Code Playgroud)

标签的唯一用途是在goto语句中,goto 语句中的标识符只能是标签:

goto a_label;
Run Code Online (Sandbox Code Playgroud)

关键字 struct、union 或 enum的结构、联合和枚举的标签(通过跟随 any32 消除歧义);

“遵循任何关键字 struct、union 或 enum”的含义正是它所说的:

struct a_tag
union another_tag
enum a_third_tag
Run Code Online (Sandbox Code Playgroud)

这些形式可以出现在类型定义、类型声明和类型使用中。如果关键字struct, union, or 中的一个enum紧跟在一个标识符之前,那么该标识符就是一个标签;否则不是。

——结构或工会的成员;每个结构或联合都有一个单独的名称空间用于其成员(通过用于通过 . 或 -> 运算符访问成员的表达式的类型消除歧义);

标识符作为.or->运算符的右侧操作数的外观将其区分为结构或联合成员的标识符。左侧操作数的类型决定了哪种结构或联合类型。C 结构和联合类型不能有静态成员,因此在没有该类型的对象的情况下,永远不需要访问相对于类型本身的结构或联合成员。

所有其他标识符,称为普通标识符

其他三种情况之一未涵盖的任何内容都包含在本案例中。这包括变量名称、函数名称、函数参数名称、内置和typedefed 类型名称以及枚举常量。(我认为这是一个完整的列表,但我可能忽略了一些东西)。

  • 命名空间如何在 C 中工作?

我唯一想澄清的另一件事是,与 C++ 不同,C 只有隐式声明和名称空间的使用。namespaceC 中没有关键字,也没有显式引用与所选命名空间相关的标识符的语法。用户定义的命名空间仅限于与结构和联合类型相关的命名空间,这种简单、隐式的方法令人满意地涵盖了所有可能的情况。

然而,鉴于普通标识符的类别非常广泛,对于可重用 C 库的作者来说,通过在其库公开的外部标识符前面加上特征短前缀来最小化名称冲突的可能性已成为惯例。这种临时命名空间完全超出了标准的范围,但很常见。