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

ffvjumwh  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(181)

我刚刚注意到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进行了测试
EDIT:我编译时出现所有警告:gcc -Wall test.c

dtcbnfnu

dtcbnfnu1#

在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)。

rjzwgtxy

rjzwgtxy2#

打开你的警告!

void foo()

是一种旧的ANSI C声明函数的方法,没有适当的原型。如果这样做,函数的行为就像void foo(...),并且允许传递任意数量的参数。
(In C++中,void foo()声明了一个空元函数,正如您所期望的那样)。

wvt8vs2t

wvt8vs2t3#

如果fextern的原型,那么艾蒂安的回答是正确的,但是讨论这一点的实际段落(C11中的6.7.6.3§14,6.7.5.3C99中的www.example.com §14)是这样读的(着重号是我的):
标识符列表仅声明函数参数的标识符。**如果函数声明符中的空列表是该函数定义的一部分,则指定该函数没有参数。**如果函数声明符中的空列表不是该函数定义的一部分,则指定不提供有关参数的数量或类型的信息。
clang(v3.4)确实会对您的文件发出警告(too many arguments in call to 'foo'),但会很乐意(并且无提示地)编译以下两个文件:
表C:

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

巴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

相关问题