16

我在打字时遇到了这个问题man 2 open。上面说open有两种,一种带两个args,一种带三个!上次我检查我们不能在 C 中重载函数。他们是怎么做到的?他们是用 C++ 编写的吗?

int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);
4

3 回答 3

19

不,他们只是使用了可变参数函数。

int open(const char * pathname, int flags, ...);

这使得最后一个参数是mode可选的。原型只显示了函数应该如何使用,而不是实际的接口。

当然,与真正的重载不同,编译器无法对mode参数进行类型检查,因此用户必须格外小心以确保仅传递 2 或 3 个参数,并且第三个参数必须是 a mode_t


顺便说一句,如果您检查man 2 openBSD(包括 OS X),它会显示正确的原型,如上

于 2010-10-17T15:38:12.420 回答
8

对于它的价值,手册页是不正确的。它显示的原型:

int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);

不等同于正确的原型

int open(const char * pathname, int flags, ...);

使用它提供的不正确的(例如,如果您自己制作函数原型而不是包含正确的标题)将导致您的程序具有未定义的行为。(这不仅仅是理论上的;它可能无法在 x86_64 和其他具有 pass-by-register ABI 的平台上运行。)

手册页试图表达(并且做得非常糟糕)的是,open参数列表的可变参数部分可以是空的或单一mode_t类型的参数,其中可选参数的缺失或存在取决于值的flags

于 2010-10-17T15:43:30.347 回答
7

不,他们用 C 语言编写,使用可变参数。

查看stdarg.h,其中有示例。

可变参数函数可以从省略号中读取任意数量的参数。实际上,函数“不想要”的任何额外参数都被丢弃了。

于 2010-10-17T15:38:09.310 回答