下一篇: , 上一篇: , 上级: 设计建议   [目录][索引]


3.4 标准 C 和 前标准 C

1989 年的标准 C 现在已经足够普及,可以在程序中使用它的特性了。有一个例外:永远不要使用标准 C 的 “三字符序列” 特性。

1999 年和 2011 年的标准 C 版本并非在所有平台上都得到完全支持。如果你的目标是支持 GCC 以外的编译器进行编译,则不应在程序中要求使用这些 C 特性。当编译器支持这些特性时,可以有条件地使用它们。

如果你的程序仅打算用 GCC 编译,那么当 GCC 支持这些特性并且它们能带来实质性好处时,你可以使用它们。

然而,在大多数程序中支持前标准编译器很容易,所以如果你知道如何做,请随意使用。

为了支持前标准 C,不要以标准原型形式编写函数定义,

int
foo (int x, int y)
…

而是像这样以预标准风格编写定义,

int
foo (x, y)
     int x, y;
…

并使用单独的声明来指定参数原型

int foo (int, int);

无论如何,你都需要这样一个声明,在头文件中,以便在所有调用该函数的文件中获得原型的好处。一旦你有了声明,通常以预标准风格编写函数定义也不会有什么损失。

此技术不适用于宽度小于 int 的整数类型。如果你认为一个参数的类型宽度小于 int,则将其声明为 int

在少数特殊情况下,此技术很难使用。例如,如果一个函数参数需要保存系统类型 dev_t,你会遇到麻烦,因为 dev_t 在某些机器上比 int 短;但你不能改用 int,因为 dev_t 在某些机器上比 int 宽。在非标准定义中,你无法安全地在所有机器上使用某个类型。支持非标准 C 并传递此类参数的唯一方法是使用 Autoconf 检查 dev_t 的宽度,并相应地选择参数类型。这可能不值得这么麻烦。

为了支持不识别原型的预标准编译器,你可能需要使用如下的预处理器宏:

/* Declare the prototype for a general external function.  */
#if defined (__STDC__) || defined (WINDOWSNT)
#define P_(proto) proto
#else
#define P_(proto) ()
#endif

下一篇: , 上一篇: , 上级: 设计建议   [目录][索引]