【发布时间】:2015-08-01 11:48:47
【问题描述】:
我奇怪地发现 C 允许链接参数列表不匹配的函数:
//add.c
int add(int a, int b, int c) {
return a + b + c;
}
//file.c
int add (int,int); //Note: only 2 arguments
void foo() {
add(1,2);
}
我先编译add.c,再编译file.c,都编译成功。奇怪的是,链接器没有给出任何错误或警告,可能原因是 C 链接器在链接时不比较参数。不过,我不是 100% 确定的。请有人对此发表评论。
现在,问题是避免这种情况或在编译期间获得某种警告的好习惯是什么,因为在我的项目中,不同文件中有很多函数,现在我们必须添加一些额外的参数在函数中。
【问题讨论】:
-
函数将像拥有所有参数一样运行,但第三个参数可能只是垃圾并导致UB。
-
@Dayalrai:不-这是未定义的行为-几乎任何事情都可能发生。在许多 ABI 上,堆栈帧将不正确,从而导致潜在的灾难性后果。
-
您有一个双重且不一致的声明。声明仅在编译时有用,因此编译器可以检查函数是否正确使用。如果您设法像以前那样欺骗编译器,链接器只会找到对
add()的调用和add()的代码并将它们链接在一起。 -
正确的做法是拥有一个包含文件,该文件公开 C 文件中的原型(函数声明)。如果你有 add.c 你必须有 add.h 其中 add.c 的函数被声明为原型......这种行为允许你避免你指出的问题。您可以使用
gcc -Wall来验证所有警告,选项--pedantic表示更多警告(但很无聊) -
我不想卷入一场投票战,但我投了赞成票,因为这是一个完全合理的问题,可以提高对“C”的理解。
标签: c arguments argument-passing