C语言 GCC调用带有太多参数的函数时的行为



我刚刚注意到GCC的一个行为对我来说似乎很奇怪(没有与其他编译器检查过)。

如果我编译以下代码:

#include <stdio.h>
void foo(int i)
{
  printf("Hello %dn",i);
}
int main(){
  foo(1, 2);
  return 0;
}

我会得到一个编译错误:

test.c:9:5: error: too many arguments to function ‘foo’

但是如果我编译这段代码:

#include <stdio.h>
void foo()
{
  printf("Hellon");
}
int main(){
  foo(1, 2);
  return 0;
}

没有错误或警告。

谁能告诉我为什么?

我用gcc 4.6.3和arm-none-eabi-gcc 4.8.3测试了这个

编辑:我编译与所有警告:gcc -Wall test.c

在C中,写void foo()意味着foo接受一个未指定数量的参数。

表示函数foo()不带参数,你应该写void foo(void)

因此,您还应该使用签名int main(void)

请注意,K&R函数声明在C23标准中已被删除(https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2841.htm)。

打开警告!

void foo()

是一种旧的ANSI C声明函数的方式,没有适当的原型。如果这样做,该函数的行为有点像void foo(...),并允许传递任意数量的参数。

(在c++中,void foo()声明了一个空函数,正如您所期望的那样)。

我认为gcc应该在这里抱怨。如果fextern原型,Étienne的答案是正确的,但讨论这一点的实际段落(C11中的6.7.6.3§14,C99中的6.7.5.3§14)是这样读的(强调我的):

标识符列表只声明函数形参的标识符。空列表中的函数声明符是该函数定义的一部分,它指定函数没有参数。函数声明符中的空列表,它不属于该函数的定义指定没有关于的数量或类型的信息参数

clang (v3.4)确实会在文件中发出警告(too many arguments in call to 'foo'),但会很高兴(并且默默地)编译以下两个文件:

foo.c:

extern void foo();
int main(){
  foo(1, 2);
  return 0;
}

bar.c:

#include <stdio.h>
void foo (int x, int y, int z) { printf("Hello %dn", z); }

结果:

$ clang -o foo bar.c foo.c
$ ./foo
Hello 1405669720

最新更新