prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 1.29

Q我如何确定哪些标识符对我来说是安全的,哪些是保留的?


A命名空间管理可能是一个棘手的问题。问题在于——这并不总是显而易见的——您不想选择已经被实现使用的标识符,这样您就会遇到“重复定义”错误,或者——更糟糕的是——悄悄地替换了实现的一个符号并导致所有东西都出错。您还希望有一些保证,以确保后续版本不会侵占您合法使用的名称。[脚注](没有什么比将一个调试好、正常工作、生产中的程序,在新的编译器版本下重新编译,结果由于命名空间或其他问题导致构建失败更令人沮丧的了。)因此,ANSI/ISO C 标准包含相当详细的定义,为用户和实现划分了不同的命名空间子集。

要理解 ANSI 的规则,并且在我们可以说给定的标识符是否保留之前,我们必须理解标识符的三个属性:它的作用域、命名空间和链接。

C 语言中有四种作用域(标识符声明生效的区域):函数、文件、块和原型。(第四种仅存在于函数原型声明的参数列表中;另请参见问题 11.5。)

有四种不同的命名空间,分别用于

另一组名称(尽管未被标准称为“命名空间”)包括预处理器宏;这些宏在编译器开始考虑四个正式命名空间之前都会被展开。

标准定义了三种“链接”:“外部”、“内部”和“无”。对我们来说,外部链接意味着全局的、非静态变量和函数(跨越所有源文件);内部链接意味着具有文件作用域的静态变量和函数;而“无链接”指的是局部变量,以及 typedef 名称和枚举常量等。

根据 ANSI 第 4.1.2.1 节的规定,这些规则概括如下:

规则 3 和 4 此外还因事实而变得复杂:几组宏名称和标准库标识符是为“未来方向”保留的,也就是说,标准日后的修订可能会定义匹配某些模式的新名称。

以下是与每个标准头文件相关的、为“未来方向”保留的模式列表:

[此处放置表格]
(符号[A-Z]表示“任何大写字母”;类似地,[a-z][0-9]表示小写字母和数字。符号*表示“任何内容”。例如,<stdlib.h>的模式表明所有以字母str后跟小写字母开头的外部标识符都将被保留。)

上述规则的真正含义是什么?如果您想确保安全,请

实际上,前面的小节过于保守。如果愿意,您可以记住以下例外情况:

然而,在利用这些例外情况之前,请认识到其中一些非常冒险(特别是例外情况 3 和 5,因为您可能会意外地#include在稍后包含相关的头文件,也许是通过一系列嵌套的#include文件),而另一些(特别是标记为 1,2 的)则代表了用户命名空间和实现保留命名空间之间的某种“无人区”。

提供这些例外情况的一个原因是为了允许各种附加库的实现者声明自己的内部或“隐藏”标识符。如果您利用了任何例外情况,您将不会与标准定义的任何标识符冲突,但您可能会与您正在使用的第三方库定义的某些内容发生冲突。(另一方面,如果您是附加库的实现者,您也可以根据需要并小心地使用它们。)

(利用例外情况 4 为函数参数或局部变量命名,这些名称匹配标准库例程或“未来方向”模式,这通常是安全的。例如,“string”是参数或局部变量的常见且合法的名称。)

其他链接:Stan Brown 的保留标识符综合列表

参考文献:ISO Sec. 6.1.2.1, Sec. 6.1.2.2, Sec. 6.1.2.3, Sec. 7.1.3, Sec. 7.13
Rationale Sec. 4.1.2.1
H&S Sec. 2.5 pp. 21-3, Sec. 4.2.1 p. 67, Sec. 4.2.4 pp. 69-70, Sec. 4.2.7 p. 78, Sec. 10.1 p. 284


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管