调用具有太多参数的函数时的GCC行为

时间:2014-07-11 14:49:14

标签: c gcc

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

如果我编译这段代码:

#include <stdio.h>

void foo(int i)
{
  printf("Hello %d\n",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("Hello\n");
}

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

我没有错误或警告。

有人能解释我为什么吗?

我用gcc 4.6.3和arm-none-eabi-gcc 4.8.3

测试了这个

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

3 个答案:

答案 0 :(得分:6)

在C中,写void foo()意味着foo采用了未指定数量的参数。

要表明函数foo()不应该参数,你应该写void foo(void)

出于这个原因,您还应该使用签名int main(void)

答案 1 :(得分:2)

打开警告!

void foo()

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

(在C ++中,void foo()声明了一个null-arity函数,因为你期望)。

答案 2 :(得分:2)

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

  

标识符列表仅声明函数参数的标识符。 空   函数声明符中的列表是该函数定义的一部分,用于指定   功能没有参数。函数声明符中不属于a的空列表   该函数的定义指定没有关于数量或类型的信息   提供参数。

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 %d\n", z); }

结果:

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