C 不完整类型:链接器不会警告明显的错误
文件 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;
A file main.c
declares a function of the incomplete type int func()
, then uses it as int func(void)
.
The function is defined in a second file as int func(int, int, int)
, which is consistent with the declaration, but not with the usage.
I would expect that kind of error to be caught by the linker, but the code compiles with no errors or warnings, even when using gcc's -Wall -Wextra -pedantic
. When debugging it with gdb, func
seems to read garbage values from the stack. Is there really no way to catch such an error?
The code discussed
// main.c
int func();
int main() {
func();
}
// func.c
int func(int a, int b, int c) {
return a * b * c;
}
Shell commands I ran
$ 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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
C 中没有像 C++ 中那样的函数重载。因此,编译器不会构建包含有关函数参数信息的损坏的函数外部名称。
在使用函数之前,您始终应该提供函数原型。在这种情况下,编译器将能够发现不一致的地方。
C 标准仅保证(6.5.2.2 函数调用)
否则
There is no function overloading in C as in C++. So the compiler does not build mangled function external names that include information about function parameters.
You always should provide function prototypes before using functions. In this case the compiler will be able to find an inconsistence.
The C Standard only guarantees that (6.5.2.2 Function calls)
Otherwise