Does gcc include some header files automatically? - c

I have the following code:
int main()
{
printf("Hello\n");
return 0;
}
I compiled it using the following command:
gcc -o myprogram myfile.c
And it compiled without any error even though I did not #include <stdio.h>. So did gcc include this header file automatically?
My gcc version is 4.3.3

In ANSI C, you can call functions you didn't declare. Such functions are implicitly declared the first time you call them. They are assumed to return int and take arguments according to the default argument promotions. Since you didn't include <stdio.h>, the compiler uses this rule and implicitly declares printf. Note that this is undefined behaviour as functions that take variable argument lists like printf must be declared explicitly. gcc usually warns you if it uses the implicit declaration rule since it's usually not intentionally used.

No, gcc did not include any header files you didn't request. #include statements are C preprocessor macros (like #define or #if) that are actually evaluated before the actual C compilation. You can see what your code looks like after all macros are resolved by calling gcc -E myfile.c. As you will see, printf will still not be declared.
If you compile with -Wall, you should get a warning that printf is undeclared. However gcc "guesses" how printf is used (probably from its arguments, but it could also simply know the routine internally). Since it finds a matching symbol name while linking, you don't get an error and your program runs just fine.
BTW, gcc 5.3.0 shows the following warning:
myfile.c: In function 'main':
myfile.c:3:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
printf("Hello\n");
^
myfile.c:3:5: warning: incompatible implicit declaration of built-in function 'printf'
myfile.c:3:5: note: include '<stdio.h>' or provide a declaration of 'printf'

Related

What libc and can I omit it's includes in my project?

I have simple program without includes that compiles with some warnings:
int main(int argc, char **argv)
{
printf("hello");
exit(0);
}
Compile:
gcc hello.c
Warning:
In function ‘main’:
warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
printf("hello");
^
warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
exit( 0 );
^
compilation command is very simple and not contains information regarding include library files that contains printf and exit. Correct me if I'm wrong, but looks that gcc links my project to these libraries by default. That points me to thinking that include files of libc libraries is not required?
Correct me once again. I got warnings because GCC somehow knows some basic functions of libc and these functions has different params. But since GCC checks all libc it founds correct function anyway.
What is libc at all. Is it some standard set of binary object and header files?
looks that gcc links my project to these libraries by default. That points me to thinking that include files of libc libraries is not required?
Includes and linking are not related that way. The includes contain function prototypes that instruct the compiler about the return value type and parameters of a given function. When a function call happens, and there is no prototype for it yet the compiler assumes it returns int and that may lead to undefined behavior.
The program will be linked to the standard libraries and function definitions will be available, but since the program was compiled with the assumption that these functions all return int there can be runtime errors related to this, which cannot be predicted since the behavior is undefined.
I got warnings because GCC somehow knows some basic functions of libc and these functions has different params. But since GCC checks all libc it founds correct function anyway.
No, it has nothing to do with gcc knowing anything but the opposite, it has to do with gcc not knowing how to call these functions.
What is libc at all. Is it some standard set of binary object and header files?
libc is a binary file libc.so.6 in current glibc and it's the runtime library with all the symbols needed by a standard c program, it does not include math.h funcions for example (that is libm.so.6).
You still need header files in your c programs for the reasons explained above, or at least declarations of the standard functions you use. These declaration are called prototypes and are required by the compiler in order to correctly compile your code.
NOTE: Always compile with at least -Wall -Werror, like this
gcc -Wall -Werror hello.c

What default libraries are taken while compiling C project with GCC

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.
The "library" in question is gcc/builtins.def from the gcc source tree.
That's not just a header file though, and it does not provide declarations for you to use. But it has proper prototypes to check yours against.
Calling undeclared exit() results in implicit declaration like this:
int exit(int);
Search "c implicit declarations" for the gory details. In this case however GCC has its own prototype for exit() from builtins.def:
void exit(int) __attribute__((nothrow,noreturn));
These declarations do not match, and that's what you are being warned about.
Your code works with warning not with error. If you add
#include <stdlib.h>
then no warning anymore ;)

gcc - pedantic wont compile, ISO C90 forbids mixed declarations and code How to fix this?

I need that code for my program to have colors. But it wont compile if i use -pedantic. Is there a way around this? its btw
gcc -pedantic MP1.c -o hahah
MP1.c: In function `main':
MP1.c:65: warning: ISO C90 forbids mixed declarations and code
MP1.c:686:30: warning: (this will be reported only once per input file)
line 65:
int originalAttrs = ConsoleInfo.wAttributes;
Move declaration of originalAttrs to the top of the scope in which it is used. The error is unrelated to use of ConsoleInfo.wAttributes but to the location of the declaration of originalAttrs. Without seeing the entire code, it is probably something like:
printf("hello\n"); /* For example. */
int originalAttrs = ConsoleInfo.wAttributes;
To fix:
int originalAttrs;
printf("hello\n"); /* For example. */
originalAttrs = ConsoleInfo.wAttributes;
Either fix the code so it complies with the C90 standard (as hmjd's answer suggests), or tell gcc to use a newer version of the standard.
C does permit mixed declarations and statements starting with the C99 standard.
If you use
gcc -std=c99 -pedantic
or
gcc -std=c11 -pedantic
it should work.

without including <stdio.h>

below given program is working without including <stdio.h>? Why does this work?
int main()
{
printf("integra");
return 0;
}
Definition of printf() is there in libc.so and the dynamic linker will take care of it even if you don't include the header file. During compile time, printf() will be an undefined symbol and it assumes that it may find the definition later on in libc. The header file will just give the proto-type and suppress the compiler(warnings) stating that the definition of the prototype is present in glibc. So basically, the header files are included just to make sure that the definitions are available in our libraries, to help the developer.
in older standard, undeclared function assume int argument and return value. Your char* have same size (32-bit) as int, so everything work.
Just don't do it.
printf() is only defined in libc.so
The dynamic linker will resolve the symbol printf() in libc since you have not included it
libc is default in gcc for every program
As Abi pointed out, your code builds successfully without including stdio.h because the linker is defaulting to the system std library for the undefined symbol (printf). GCC would normally warn you of such cases.
Let test.c be:
1: int main()
2: {
3: printf("test\n");
4: return 0;
5: }
Building test.c with GCC 4.2.1 on Mac OSX:
$ gcc test.c
test.c: In function ‘main’:
test.c:3: warning: incompatible implicit declaration of built-in function ‘printf’
$ ./a.out
test
You can disable this default linking by specifying a GCC linker option -nostdlib (or -nodefaultlibs) along with -lgcc (as the GCC manual recommends):
$ gcc -nostdlib -lgcc test.c
test.c: In function ‘main’:
test.c:3: warning: incompatible implicit declaration of built-in function ‘printf’
Undefined symbols:
"_puts", referenced from:
_main in cc3bvzuM.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
Some (old?) compilers do not require prototypes before calling functions.
When you use a function that has not been declared, then the compiler will assume this function returns an int and takes an unspecified, but fixed, number of arguments.
If this assumption matches with the definition of the function, and if the arguments you provided also match (modulo the default argument promotions) the parameters that the function expects to receive, then everything is well.
If the assumption is incorrect (like for printf, which is a variadic function), or when the arguments don't match, the results are undefined. One of the nasty things of undefined behaviour is that it can appear to work as expected.

warning: incompatible implicit declaration of built-in function ‘xyz’

I'm getting a number of these warnings when compiling a few binaries:
warning: incompatible implicit declaration of built-in function ‘strcpy’
warning: incompatible implicit declaration of built-in function ‘strlen’
warning: incompatible implicit declaration of built-in function ‘exit’
To try to resolve this, I have added
#include <stdlib.h>
at the top of the C files associated with this warning, in addition to compiling with the following flags:
CFLAGS = -fno-builtin-exit -fno-builtin-strcat -fno-builtin-strncat -fno-builtin-strcpy -fno-builtin-strlen -fno-builtin-calloc
I am using GCC 4.1.2:
$ gcc --version
gcc (GCC) 4.1.2 20080704
What should I do to resolve these warnings?
In C, using a previously undeclared function constitutes an implicit declaration of the function. In an implicit declaration, the return type is int if I recall correctly. Now, GCC has built-in definitions for some standard functions. If an implicit declaration does not match the built-in definition, you get this warning.
To fix the problem, you have to declare the functions before using them; normally you do this by including the appropriate header. I recommend not to use the -fno-builtin-* flags if possible.
Instead of stdlib.h, you should try:
#include <string.h>
That's where strcpy and strncpy are defined, at least according to the strcpy(2) man page.
The exit function is defined in stdlib.h, though, so I don't know what's going on there.
In the case of some programs, these errors are normal and should not be fixed.
I get these error messages when compiling the program phrap (for example). This program happens to contain code that modifies or replaces some built in functions, and when I include the appropriate header files to fix the warnings, GCC instead generates a bunch of errors. So fixing the warnings effectively breaks the build.
If you got the source as part of a distribution that should compile normally, the errors might be normal. Consult the documentation to be sure.
Here is some C code that produces the above mentioned error:
int main(int argc, char **argv) {
exit(1);
}
Compiled like this on Fedora 17 Linux 64 bit with gcc:
el#defiant ~/foo2 $ gcc -o n n2.c
n2.c: In function ‘main’:
n2.c:2:3: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]
el#defiant ~/foo2 $ ./n
el#defiant ~/foo2 $
To make the warning go away, add this declaration to the top of the file:
#include <stdlib.h>
I met these warnings on mempcpy function. Man page says this function is a GNU extension and synopsis shows:
#define _GNU_SOURCE
#include <string.h>
When #define is added to my source before the #include, declarations for the GNU extensions are made visible and warnings disappear.

Resources