c - C 中的 "struct namespace"是否有技术原因?

标签 c namespaces

在 C 语言中,大多数声明结构的代码都遵循这种模式:

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

/* struct definition */
typedef struct T
{
   /* etc. */
} T ;

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

在 C++ 中,这个问题得到了缓解,因此您可以省略类型定义部分。在 C# 和 Java 中,设计者甚至都懒得理会。所以这些语言无助于理解为什么 C 会那样做。

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

是否有技术原因将 struct T 置于与其他普通标识符不同的命名空间中?

编辑

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

6.1.2.3 Name spaces of identifiers

It 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:

  • [...]

  • the tags of structure, unions and enumerations (disambiguated by following any of the keywords struct, union, or enum).

  • [...]

  • all other identifiers. called ordinary identifiers (declared in ordinary declarators or as enumeration constants).

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

最佳答案

在添加 typedef 使解析复杂化之前,对象声明总是以保留字开头:structintchar floatdouble,可能还有 longunion(不确定是否添加了这些typedef 之前或之后)。由于结构标记只能出现在关键字 struct 之后,因此编译器没有理由关心结构标记是否与任何其他标识符共享名称。

需要将 typedef 名称与任何其他标识符的名称区分开来是由于允许在对象声明或强制转换表达式中使用自定义类型而不使用任何保留字或标点符号而产生的语法歧义。 (在函数的开头,x * y; 可以创建一个名为 y 的类型为 x* 的对象,或者可以乘以 x by y 并丢弃结果,并且 (x)(y) 可以将 y 转换为类型 x 或使用参数 y 调用函数 x

关于c - C 中的 "struct namespace"是否有技术原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27212766/

相关文章:

android - CLONE_NEWNS 在 Android 上无效

c++ - 为什么两个不同的未命名命名空间可以在一个 cpp 文件中共存?

C双指针

c - Unix:使用 Make 进行项目管理

c++ - gcc -O2 的奇怪整数行为

c - strtok_r 保存状态行为

c - ANSI C - 将数据从函数传递到 CHAR 指针

ruby - 如何在不手动加载类的情况下获取命名空间中的所有类?

linq - 无法解析 System.Linq 命名空间

android - 在 Android 中使用命名空间处理 RSS 提要