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