使用C语言定义一个没有参数的函数原型

5
这个问题是 “C++11或C中f(void)表示无参数的含义?” 的衍生问题。
许多人已经回答了这个问题,并认为在C语言中,函数原型的含义为没有参数。
void func ()

这里的"func"是一个返回空值(void)且参数在此时未知的函数。

此外,他们认为可以这样声明并使用一些参数调用该函数:

func (1, 2, 3);

所以,我做了这个,我进行了一个测试来验证它是否有效,我并不惊讶它是有效的。

这里是func.c,其中包含main()函数。

#include <stdio.h>

extern void func ();

int main (int ac, char ** av)
{
  func (1, 2, 3);

  return 0;
}

这里是func1.c,其中包含函数func()

#include <stdio.h>

void func (int a, int b, int c)
{
  printf ( "%d, %d, %d\n", a, b, c );
}

这里是我的问题:

问题1:

当我运行此程序时,我得到了预期的输出1、2、3。编写代码的这种方式是安全的吗?也就是说,可以假设ABI(应用二进制接口)可靠地确保在main()中调用func()会将三个参数放置在正确的位置(寄存器、堆栈等),以便func()找到它们吗?

问题2:

如果以上问题的答案是这是一种安全的做法,那么如果func()是用其他语言实现的,您的答案是否会改变?


1
即使在C语言中是安全的(出于明显的原因,我会说不是),在C++中也是非法的。 - juanchopanza
2
据我所知,在C语言中是安全的。1, 2, 3是类型为int的字面量——当您调用foo(1, 2, 3)时,假定未知的原型为void (int, int, int) - user529758
1
请记住,在C语言中没有函数重载。这是C语言和C++之间的一个重大区别。 - Bathsheba
1
@Walter 空参数列表不能用于指定可变参数。 - user529758
@H2CO3,好的,这就是我所说的不安全的意思。我应该表达得更清楚一些。 - juanchopanza
显示剩余6条评论
2个回答

12

你是在问关于C还是C++的问题?

C最初没有函数原型。写法如下:

extern void func();

然后定义它:

void func( a, b, c )
    int a;
    int b;
    int c;
{
    //  ...
}

C++添加了函数原型,并使上述内容不再合法。同时保留如下声明:

extern void func();

声明了一个没有参数的函数;调用它时使用参数是错误的,定义它时也是如此。

C++从C中添加了函数原型。但为了避免破坏现有代码,它不需要它们,并对待

extern void func();

与之前一样:一个接受未知数量和类型参数的函数。因此它还添加了:

extern void func(void);

作为表明函数不需要任何参数的特殊方式。由于C兼容性的原因,C++添加了这个特殊情况。

在C++中的一般规则是只需编写:

extern void func();

只有在需要兼容两种语言的头文件中才会使用带有void的形式。当然,在C语言中,这个形式并不起作用,所以必须添加void。(暂时而言,从我了解的情况来看,C已经弃用了旧的形式,因此将来可能会与C ++在这方面表现完全一样。)

编辑:

查阅C11标准,第6.11.6节:

使用带有空括号的函数声明符(不是原型格式参数类型声明符)是一个荒废的特性。

在C中不要这样做。


引用标准自动加一分 :) - Vorac

1

问题1:如果参数是正确的类型,那么它可能会工作(很可能会)。但是尝试 func(1.2, "blah"); 看看会发生什么-它可能在“工作”意义上不会崩溃-当然它会编译。

问题2:请参考问题1的答案。这一点根本不安全。


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