Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2306426
  • 博文数量: 527
  • 博客积分: 10343
  • 博客等级: 上将
  • 技术积分: 5565
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-26 23:05
文章分类

全部博文(527)

文章存档

2014年(4)

2012年(13)

2011年(19)

2010年(91)

2009年(136)

2008年(142)

2007年(80)

2006年(29)

2005年(13)

我的朋友

分类: C/C++

2006-08-28 21:22:02

    unix 的 man page显示了下面的open函数原型:
    int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);

    它提示我们有两个版本的open函数, 你用两个参数调用它就调用两个参数的版
    本, 给三个参数就调用三个参数的版本, 似乎很神奇.

    这样的写法给人以假象.

    K&R的bible 里8.3节讲UNIX接口的OPEN函数, 也没有提到这点:
===========================
To open an existing file for reading,
fd = open(name, O_RDONLY,0);
The perms argument is always zero for the uses of open that we will discuss.
===========================
    实际上在这种情况下第三个参数是多余但无害的.

    问题是, 这是C语言, 它没有C++的overload机制, 一个函数的签名是不包括参
    数部分的, 编译器如何实现? 编译器对名为open的函数特别对待? 可能性不大
    .

    曾经有段时间我还肤浅地对人说过, 其实C语言中就有了C++的overload机制的
    原型, UNIX的open 系统调用就有两个参数的版本.

    然而, 这只是一种假象.

    open的真正原型是:
    extern int open (__const char *__file, int __oflag, ...)
    它是变参函数.
    当 __oflag中有 O_CREAT时, 才会需要后面的一个参数. 然而open的实现却不
    象printf 那样表现出可传递参数在实用中的多变性. 它只有两种真正有用的
    可能性: 2个参数或3个参数.

    由于原型的机制, 使得C语言没有办法阻止你写多于3个的参数, 只不过,
    open的实现不会理会你传递给它的那些多余的参数, 而函数调用的参数传递机
    制又会正确地消除你额外传递的垃圾参数而引起的堆栈开销. 所以, 并无害
    处. 但下面的写法是正确的:

    open("abc.txt", O_RDONLY, S_IRWXU);
    因为第二个参数中没有 O_CREAT, 所以open的实现不会去检查第三个参数.
    而
    open("abc.txt", O_WRONLY | O_CREAT, S_IRWXU, 1, 2, "asdf");
    这样的写法也是合法的. gcc 加了参数-Wall也没有给出任何警告.

    这正如 printf("%d", 1 ,2 ,3 , "adf" );
    完全合法一样, 只不过 gcc特别为printf作了考虑, 它会用内窥镜看到printf
    的内部, 深入其五脏六腑做检查, 第一个格式化字串内的每个格式转换说明符
    与后面的参数是否类型匹配. 你调用printf时搞错了这个gcc是会有提醒的,
    前提是你用了-Wall 参数.
阅读(1542) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~