函数原型声明无法编译

时间:2016-03-30 00:45:39

标签: c gcc

我是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)。

2 个答案:

答案 0 :(得分:3)

问题是P预处理器宏。 C书中的编译器设计是陈旧的,因此作者为类似的旧(现在是古老的)编译器提供了关于参数列表的解决方法。这本书描述了它的用途:

  

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

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

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

  int dimitri ( int x, long y );
     

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

     

int dimitri();

这个想法是,如果您有一个符合ANSI标准的编译器,那么在包含定义#define ANSI的头文件之前,您应该P。然后P单独留下您的参数列表。但是,如果您没有符合ANSI标准的编译器,则不会定义ANSI,并且预处理器会删除您的参数列表。 P看起来像这样:

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

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

答案 1 :(得分:-2)

在SET *

之后删除逗号

它不应该在那里。