当我阅读一些在 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;
{
}
问题是我不知道为什么要在参数列表前加上“_”。
最佳答案
_
是一个宏,旨在允许代码使用原型(prototype)(指定参数类型的函数声明),同时仍然与不支持原型(prototype)的 pre-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 年后的今天,很少有不支持原型(prototype)的 C 编译器在使用,因此对此类宏的需求基本上已过时。但即使是 2011 年发布的最新 ISO C 标准,仍然支持旧式非原型(prototype)函数。
请注意,源代码中没有任何内容实际定义了 PROTOTYPES
宏,因此,如果您想在启用原型(prototype)的情况下编译代码(以进行额外的编译时检查),您需要手动编辑 makefile
,更改为:
COPTS = -O
为此:
COPTS = -O -DPROTOTYPES
即使进行了该更改,由于 malloc
的重新声明无效,编译仍然失败。该代码需要一些工作才能使其符合现代标准。
关于c - 为什么在参数列表前加一个 "_",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39946122/