C 不完整类型:链接器不警告明显错误

C incomplete types: linker doesn't warn about obvious error

一个文件main.c声明了一个不完整类型int func()的函数,然后将其用作int func(void)

该函数在第二个文件中定义为int func(int, int, int),与声明一致,但与用法不一致

我希望链接器能够捕获这种错误,但代码编译时没有错误或警告,即使使用 gcc 的 -Wall -Wextra -pedantic。使用 gdb 调试时,func 似乎从堆栈中读取垃圾值。真的没有办法捕捉到这样的错误吗?

讨论的代码

// main.c
int func();

int main() {
    func();
}

// func.c
int func(int a, int b, int c) {
    return a * b * c;
}

Shell 命令我 运行

$ gcc main.c func.c -Wall -Wextra -pedantic -ggdb
$ gdb -q a.out
Reading symbols from a.out...
(gdb) b 1
Breakpoint 1 at 0x1131: file main.c, line 4.
(gdb) r
Starting program: /tmp/example/a.out 

Breakpoint 1, main () at main.c:4
4               func();
(gdb) s
func (a=1, b=-8376, c=-8360) at func.c:2
2               return a * b * c;

C 中没有像 C++ 中那样的函数重载。因此,编译器不会构建包含函数参数信息的错位函数外部名称。

在使用函数之前,您始终应该提供函数原型。在这种情况下,编译器将能够发现不一致。

C 标准仅保证(6.5.2.2 函数调用)

2 If the expression that denotes the called function has a type that includes a prototype, the number of arguments shall agree with the number of parameters. Each argument shall have a type such that its value may be assigned to an object with the unqualified version of the type of its corresponding parameter.

否则

6 If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined.