函数指针声明 - __P 是什么意思?

8
通常函数指针的定义形式如下:
 int function(int, int);
 int (*ptr)(int, int);

今天我看到一个表格,但是我不理解它。有人可以解释一下吗?
int (*close)    __P((struct __db *));

这是C还是C++?(请在问题中添加标签)。你知道__P宏是什么吗? - Rup
1
C,我已经添加了标签。我不知道_P是宏。我们的老师要求我们学习berkeleyDB中的源文件,但我不擅长C语言。 - Cruisehu
3个回答

12

__P() 宏通常用于支持 K&R C 时代的 C 实现,当时还没有原型(原型是在 C89 中引入的)。基本逻辑是

#if SOME_LOGIC_TO_TEST_WHETHER_IMPLEMENTATION_SUPPORTS_PROTOTYPES
#  define __P(argument_list) argument_list
#else
#  define __P(argument_list) () 
#endif

你能看到这种应用于你的例子时如何工作吗?请注意,为了使其正常工作而不导致语法错误,参数列表必须包括函数调用的括号,而不仅仅是类似函数的宏的括号。因此,在使用宏时需要双重括号。那可能就是为什么它看起来不寻常的原因。


谢谢你的回答。我们老师要求我们学习berkeleyDB中的源文件。我在那一点上卡住了。我不擅长C语言。我想我应该多学习一些关于C语言的知识。 - Cruisehu
@Maybe_hu 这是一门很棒的语言,比C++更加简单、优雅(C++并不是C的超集,而是一门完全不同的语言,只是偶然共享了一些语法和历史)。 - Jens
那么对于我来说,我应该阅读哪些书籍或网站呢?你能为我推荐一些吗? - Cruisehu
1
只有一本书是必不可少的:Kernighan,Ritchie,C语言程序设计,第2版。这些是该语言的作者。其他任何东西都只是个人意见 :-) - Jens
1
@Jens 除了今天的语言已经有所不同之外,它并不意味着语言的作者是最好的讲解者。我认为这是一本好书,但这是因为它自身的优点,而不是因为作者是谁。 - David Heffernan
显示剩余8条评论

9

__P()只是一个宏。在我的系统中,它被定义如下(在sys/cdefs.h中):

#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos)     protos          /* full-blown ANSI C */
#else   /* !(__STDC__ || __cplusplus) */
#define __P(protos)     ()              /* traditional C preprocessor */
#endif  /* !__GNUC__ */

从这个描述中可以看出,它似乎用于与(非常)老的编译器保持兼容性。


在函数声明中使用,例如:int functionname __P((int)),我们将会得到完整的ANSI int functionname (int)传统的C预处理器 int functionname ()。这是有效的,因为“早期的K&R C”确实有函数声明,如果仅指定返回类型而不是参数类型,则使用了括号()来替换参数。 - humanityANDpeace

2
常见的函数指针定义形式是...但我今天看到了一种不理解的形式。
这里没有什么特别的,没有魔法语法。这不是函数指针声明的不同形式。
这只是函数指针声明的标准形式,而 "__P()" 是由您使用的头文件中定义的宏。因此,请找到该宏定义以了解其目的。

或者可以有条件地定义它返回其参数或什么也不返回。后一种情况是K&R C的遗留问题,因为它没有原型。旧的库仍然包含这个hack。 - Gene
@Gene 我并不是在试图了解__P的作用。事实上,我已经删除了我的猜测。我想表达的观点是这不是另一种语法,而只是标准语法和宏。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接