为什么要添加" _"在参数列表之前

时间:2016-10-09 16:57:25

标签: c gcc

当我阅读一些在linux上运行并由gcc编译的代码时,我遇到了这样的声明:

void* (*func_name) _((void *buf, int size)) 

BGET源代码是:

void bectl _((int (*compact)(bufsize sizereq , int sequence), 
    void *(*acquire)(bufsize size),
    void *(*release)(void *buf),
    bufsize pool_incr));
void bectl(compact, acquire, release, pool_incr)
    int(*compact) _((bufsize sizereq, int sequence));
    void *(*acquire) _((bufsize size));
    void (*release) _((void *buf));
    bufsize pool_incr;
    {

    }

问题是我不知道为什么要添加" _"在参数列表之前。

1 个答案:

答案 0 :(得分:6)

_是一个宏,旨在允许代码使用原型(指定参数类型的函数声明),同时仍然与不支持原型的ANSI前编译器兼容。

请注意_是有效的标识符。但是,所有以_开头的标识符都保留在文件范围内使用,因此这是代码可能不可移植的另一个原因。

您正在阅读的代码显然是BGET,可用here。 (在您的问题中引用来源会很有帮助。)如果查看bget.h头文件(1995年最后更新),您将看到:

#ifndef _
#ifdef PROTOTYPES
#define  _(x)  x                      /* If compiler knows prototypes */
#else
#define  _(x)  ()                     /* It it doesn't */
#endif /* PROTOTYPES */
#endif

今天,21年后,使用的C编译器很少支持原型,因此对这些宏的需求基本上已经过时了。但即使是2011年发布的最新ISO C标准,仍然支持旧式的非原型功能。

请注意,源中没有任何实际定义PROTOTYPES宏的内容,因此如果要在启用原型的情况下编译代码(以获得额外的编译时检查),您可以“我需要手动编辑makefile,更改此内容:

COPTS = -O

到此:

COPTS = -O -DPROTOTYPES

即使进行了此更改,由于malloc的重新声明无效,编译仍然失败。该代码需要一些工作才能达到现代标准。