Why does an invalid use of C function compile fine without any warnings?
I'm more like C++ than C, but this simple example of code is big surprise for me:
int foo() {
return 3;
}
int main() {
int x;
foo(&x);
return x;
}
https://godbolt.org/z/4ov9nTzjM
No warnings, no linking issues still this code is invalid.
I've stumbled on this when some beginner filed a question with code having this strange issue. Question was asked on some other site (none English one) and I'd like to provide him better explanation why it compiles (and learn something about C). His original code if some one needs to see it.
I'm suspecting that this sis somehow related to implicit function declaration, but I'm not fully sure. Why compiler doesn't complain that foo
is called with arguments?
Update:
Here is an assembly:
foo:
push rbp
mov rbp, rsp
mov eax, 3
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
lea rax, [rbp-4]
mov rdi, rax
mov eax, 0
call foo
mov eax, DWORD PTR [rbp-4]
leave
ret
as you can see x
remains uninitialized.
Solution 1:
The compiler should issue a message for this program
int foo() {
return 3;
}
int main() {
int x;
foo(&x);
return x;
}
because the function foo called with an argument though its identifier list is empty. So the program has undefined behavior.
According to the C Standard *6.7.6.3 Function declarators (including prototypes) )
14 An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters. The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied.
So the program is invalid.
You could make it a valid program the following way
int foo();
int main() {
int x;
foo(&x);
return x;
}
int foo( int *p ) {
return 3;
}
Though the compiler can issue a warning that the parameter p
is not used.
In this case the function declaration that is not its definition means that there is no information about the number and types of parameters.
Opposite to C in C++ this declaration
int foo();
is equivalent to
int foo( void );
Solution 2:
This function is 100% correct.
In the C language int foo() {
means: define function foo
returning int
and taking unspecified number of parameters.
Your confusion comes from C++ plus where int foo(void)
and int foo()
mean exactly the same.
In the C language to define function which does not take any parameters you need to define it as:
int foo(void) {