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;
CodePudding user response:
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)
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.
Otherwise
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.