我在打字时遇到了这个问题man 2 open
。上面说open有两种,一种带两个args,一种带三个!上次我检查我们不能在 C 中重载函数。他们是怎么做到的?他们是用 C++ 编写的吗?
int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);
我在打字时遇到了这个问题man 2 open
。上面说open有两种,一种带两个args,一种带三个!上次我检查我们不能在 C 中重载函数。他们是怎么做到的?他们是用 C++ 编写的吗?
int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);
不,他们只是使用了可变参数函数。
int open(const char * pathname, int flags, ...);
这使得最后一个参数是mode
可选的。原型只显示了函数应该如何使用,而不是实际的接口。
当然,与真正的重载不同,编译器无法对mode
参数进行类型检查,因此用户必须格外小心以确保仅传递 2 或 3 个参数,并且第三个参数必须是 a mode_t
。
顺便说一句,如果您检查man 2 open
BSD(包括 OS X),它会显示正确的原型,如上。
对于它的价值,手册页是不正确的。它显示的原型:
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
。