This question comes from an attempt to understand the "C philosophy" and not from any "real problem".
Suppose that in a C program I use sin(x):
#include <stdio.h>
int main() {
char s[20] = "aha";
printf("%f", sin(s));
return 0;
}
I have deliberately made two mistakes:
#include
ed math.h (or provided any declaration for sin).s
of type char *
(just something that cannot be cast meaningfully to a double
).I compile using GCC with the -lm
flag.
As expected, I get one warning and one error.
Of course, there is the warning of implicit declaration of function blah blah:
bad.c: In function ‘main’:
bad.c:5:15: warning: implicit declaration of function ‘sin’ [-Wimplicit-function-declaration]
5 | printf("%f", sin(s));
| ^~~
bad.c:5:16: warning: incompatible implicit declaration of built-in function ‘sin’
bad.c:2:1: note: include ‘<math.h>’ or provide a declaration of ‘sin’
1 | #include <stdio.h>
+++ |+#include <math.h>
A little research seems to indicate that if a function is not declared beforehand, then C assumes a "default declaration" (the so called "implicit declaration") which is like int undeclaredfunction(void)
.
But I also get the following error:
2 |
bad.c:5:19: error: incompatible type for argument 1 of ‘sin’
5 | printf("%f", sin(s));
| ^
| |
| char *
bad.c:5:20: note: expected ‘double’ but argument is of type ‘char *’
This shows that the "implicit declaration" expects an argument
of type double
.
gcc
or clang
)?#include<math.h>
? Just because of tradition? Or neatness?The answer(s) that I looking for are about the exact rules used by the compiler, and not about subjective comments about "good programming practices".
The C standard gives little if any mention of built-in functions, however some C implementations have a set of built-in functions that are "predeclared", so to speak.
For GCC in particular, the following page lists the built-in functions:
7 Built-in functions provided by GCC
And this page in particular lists C library functions that are built in:
7.1 Builtins for C library functions
The sin
function is among this list, so the proper declaration of double sin(double)
exists as a built-in.
If this same code is compiled under MSVC, it does not generate an error. Their list of built-in functions can be found here:
And apparently sin
is not among its list of built-in functions, so it uses the implicit declaration of int sin()
(note that prior to C23 this is not the same as int sin(void)
, as the former has an unspecified number of arguments while the latter has zero). Subsequently running the program would trigger undefined behavior as the sin
function is being called through an incompatible function pointer.