我奇怪地发现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%肯定它。有人请对此发表评论。
现在,问题是在编译期间避免这种情况或得到某种警告的好习惯是什么,因为在我的项目中,不同文件中有很多功能,现在&那么我们必须在函数中添加一些额外的参数。
答案 0 :(得分:7)
正确使用您的标题文件。
配置编译器以发出尽可能多的警告
注意警告!
<强> add.h 强>
#ifndef ADD_H_INCLUDED
#define ADD_H_INCLUDED
int add(int a, int b, int c);
#endif
<强> add.c 强>
#include "add.h"
int add(int a, int b, int c) {
return a + b + c;
}
<强> file.c 强>
#include "add.h"
void foo() {
add(1, 2);
}
答案 1 :(得分:5)
调用具有少量参数的函数会导致undefined behavior,因为这些参数的值将是不确定的。
答案 2 :(得分:5)
C链接器在链接时不会比较参数。
这是正确的。与将参数类型视为函数签名一部分的C ++链接器不同,C链接器仅考虑函数名称。这就是为什么只能通过以你所展示的方式提供错误的函数原型来创建具有未定义行为的情况。
在编译过程中避免这种情况或得到某种警告的好习惯是什么?
始终将要分享的函数原型放入标题中,并在使用函数的位置和定义函数的位置包含该标题。这将确保编译器发出诊断消息。将所有编译器警告视为错误。 C编译器通常相当宽容,因此它们的警告通常表明非常重要。