我是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*后的逗号
它不应该在那里。