c函数原型声明编译失败



我是c的新手。我正在试着通读Holub的Compiler Design In C。在本书附录a中一个名为set.c的文件中,作者使用了一个function prototype声明,如下所示。

extern int      _addset     P((SET* , int ));

对我来说,这在编译过程中失败。下面列出了错误。我正在使用gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4

include/tools/set.h:25:37: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘P’
 extern void     delset              P((SET* ));

当我按照如下所示更改声明时,代码就会编译。

extern int      _addset(SET* , int );

由于我不太熟悉c,我不确定这样更改代码是否做错了什么。有人能告诉我以上语法是否有效吗?为什么书中的语法不编译?Holub确实强调了使用ANSI C的重要性,但根据我所读到的GCC符合ANSI(或者更确切地说是ISO)。

问题出在P预处理器宏上。C书中的编译器设计是旧的,所以作者为类似的旧(现在是旧的)编译器提供了一个关于参数列表的变通方法。这本书描述了它的用途:

第25行和第28行的p宏处理另一个与ANSI相关的可移植性问题。许多编译器(包括许多UNIX编译器)无法处理函数原型。此宏使用类似的机制到前面讨论的D()宏,以将原型转换为如果未定义ANSI,则使用简单的外部声明。例如,给定以下输入:

  int dimitri P(( int x, long y ));

如果定义了ANSI,则p(x)宏计算为其参数以下翻译结果:

  int dimitri ( int x, long y );

否则,宏将丢弃其参数并计算为(),因此将创建以下内容:

int dimitri();

这个想法是,如果你有一个符合ANSI的编译器,那么在包含定义P的头文件之前,你应该先#define ANSI。那么P就不用理会你的论点列表了。但是,如果您没有符合ANSI的编译器,则不会定义ANSI,预处理器会删除您的参数列表。P看起来像这样:

#ifdef ANSI
#define P(x) x
#else
#define P(x) ()
#endif

我建议像您一样完全删除P。但是,如果您希望能够按原样复制和粘贴书本中的代码,也可以使用#define ANSI#define P(x) x

删除SET*后的逗号

它不应该在那里。

最新更新