c - 为什么在参数列表前加一个 "_"

标签 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;
    {

    }

问题是我不知道为什么要在参数列表前加上“_”。

最佳答案

_ 是一个宏,旨在允许代码使用原型(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/

相关文章:

c - 我是否转换 malloc 的结果?

c - Linux - 从内核内部发送数据包

c - 选择 int 中的所有其他数字

c - 在 OSX 和 Ubuntu 上构建打补丁的 64 位 OpenSSL

c++ - 使用 fread() 和 UDP 套接字通过网络传输 pdf 文件

c - 统计返回 ENOENT

c++ - 对纯 C++ 函数进行基准测试

c++ - 如何减小可执行文件的大小?

c - GCC优化步骤

c++ - 错误 'a.out' : free(): invalid next size (normal)