C 中的“结构命名空间”有技术原因吗?

pae*_*bal 6 c namespaces

在 C 中,大多数声明结构体的代码将遵循以下模式:

/* struct forward-declaration */
typedef struct T T ;

/* struct definition */
typedef struct T
{
   /* etc. */
} T ;
Run Code Online (Sandbox Code Playgroud)

这是非常普遍的,大多数与我交谈过的开发人员甚至都不知道上面的代码同时做了两件事(结构声明,然后在正常命名空间中为结构名称设置别名),只是出于习惯而编写它。

在 C++ 中,该问题得到缓解,因此您可以省略 typedefing 部分。在 C# 和 Java 中,设计人员甚至都没有打扰。所以这些语言无助于理解为什么 C 会这样做。

所以,在Oliver Charlesworth的建议之后:

是否有技术原因struct T将名称空间与其他普通标识符分开?

编辑

C89/C90标准中的相关部分是:

6.1.2.3 标识符的命名空间

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

  • [...]

  • 结构、联合和枚举的标签(通过跟随任何关键字structunionenum 来消除歧义)。

  • [...]

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

C11(n1570:6.2.3 标准草案)的文本大致相同。

unw*_*ind 0

仅当您想使用第二个声明中的struct T名称进行引用时才需要第一行。T

对于不包含此类引用的结构,仅需要第二种形式。对于这种情况,为了简单起见,我建议删除当时毫无意义的结构标记:

typedef struct {
  /* interesting fields go here */
} T;
Run Code Online (Sandbox Code Playgroud)

此外,它typedef不会“将结构名称带入正常名称空间”,它会为不同的类型名称创建(像typedef往常一样)别名( ) 。当然,这里的名称拼写之间没有任何联系,这就是为什么我建议首先删除标记,它只是添加了一个大多数时候毫无意义的名称。Tstruct Tstruct