I have simple application:
#include <stdio.h>
int main( int argc, char ** argv )
{
printf( "hello");
exit( 0 );
}
When I compile it with command
gcc -c count_words.c
I have warning:
warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
exit( 0 );
I was trying to find where exit()
function is defined. And found that it is defined in stdlib.h
. But it is not included in my project and no additional libs defined in compile command.
Correct me if I'm wrong, but looks like gcc
takes some libs as default. What are these libs and is it possible to tell gcc not include them?
Why compiler is not happy regarding exit(0)
assuming that it somehow includes stdlib.h
as default?
Let's take your example:
#include <stdio.h>
int main( int argc, char ** argv )
{
printf("hello\n");
exit(56);
}
Although we get a warning on compilation:
~$ gcc test.c -o test
test.c: In function ‘main’:
test.c:6:5: warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration]
exit(56);
^
test.c:6:5: warning: incompatible implicit declaration of built-in function ‘exit’
test.c:6:5: note: include ‘<stdlib.h>’ or provide a declaration of ‘exit’
Anyway, I think you have tried to run it and make sure it works:
~$ ./test
hello
~$ echo $?
56
@Mat was right when he said that:
You're mixing up including headers and linking to libraries. Those are two completely different things
The C
compiler and linker are totally separate tools. Let's look on this. Actually, this program depends on the standard C library (as all programs if you didn't pass -nostdlib
to compiler) and a couple of system libraries (like loader and vdso). You may see it with:
~$ ldd test
linux-vdso.so.1 (0x00007fff1b128000)
libc.so.6 => /lib64/libc.so.6 (0x00007f804389f000)
/lib64/ld-linux-x86-64.so.2 (0x0000557744537000)
These three library is a minimal set for any program. The exit
function is defined in the standard library or libc.so.6
in our case. Now let's look on the compilation process in verbose mode. You can achieve this by the passing -v
or --verbose
option to compiler:
gcc test.c -o test --verbose
If you will execute this, you will find lines like these:
#include <...> search starts here:
/usr/lib/gcc/x86_64-redhat-linux/5.3.1/include
/usr/local/include
/usr/include
So, compile knows where to search header files for stdlib
and it starts to search it to find declaration for non-local functions. Note that it searches only in header files which are included in your source code file. It can find printf
declaration in thestdio.h
, but can't locate declaration of the exit
.
After this step, the compile starts to link your program with libraries:
/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/collect2 ... -lc ...
Where collect2
is gcc util which tries to link your program with lc
which is standard C library. Note that the process consists from two steps: compilation and linking. That's why your program works.
Additionally, gcc
supports -M
option which will tell you about dependencies of the main file. So, if you will execute it, you will see the set of header files including stdio.h
, but not stdlib.h
:
$ gcc -M test.c
test.o: test.c /usr/include/stdc-predef.h /usr/include/stdio.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
/usr/include/gnu/stubs-64.h \
/usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/typesizes.h \
/usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
/usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
Or even better, try to pass -E
option to gcc
:
$ gcc -E test.c
and you will see result right after the first stage - preprocessing stage. I think it is the easiest way to understand why you are getting this warning.
assuming that it somehow includes stdlib.h as default?
It simply doesn't. That wouldn't be standards-compliant.
So, when you use exit
, it has never been declared, so there's you implicit declaration upon usage. However, the fact to you implement exit
nowhere else will only become a problem at the final linkage.
Now, GCC knows damn well that you are about to get into trouble, so it warns you.
Simply actually include stdlib.h and you should be fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With