I haven't touched on c++ for a while and this question might be stupid but it indeed bothers me for a while.
Suppose I have the following c program:
#include <stdio.h>
int main()
{
int i;
for(i=0; i<10; i++)
{
printf("Hello World!\n");
}
return 0;
}
I know the reason I include stdio.h
is because I call printf
in main
but I'm wondering how compiler would know where to find the implementation of printf()
during the compilation? stdio.h
only provides function prototype but what exactly is happening during the compilation?
Will there be certain prefixed path that compiler knows to search for the implementation of printf
? If so, how to find them?
Thanks much!
Chances are if you're on a linux system, the C library used is glibc
. GCC doesn't actually provide a C library implementation, only the header files. It's the job of the C library to actually implement the definition of these functions. On Linux, there's something called "shared libraries" which are loaded dynamically by programs that need it. For example:
ldd /usr/bin/gcc
linux-vdso.so.1 (0x00007ffd9e9f8000)
libm.so.6 => /lib64/libm.so.6 (0x00007ff9a35a6000)
libc.so.6 => /lib64/libc.so.6 (0x00007ff9a31de000)
/lib64/ld-linux-x86-64.so.2 (0x000055953c573000)
You can disable the linking of libc
by passing -nostdlib
and link in your own C library. There are also other ways to replace definitions provided by the C library, like linking in your own malloc
and so on. The linker is only allowed to find one definition for any given declaration and since there is no name mangling in C, it's easy to do so.
This is an oversimplified explanation, and doesn't mention builtins, the math library or the like.
printf
is part of standard library, which is called "standard" because it is linked by default by C compiler. Standard library is typically provided by operating system or compiler. On most linux systems, it is located in libc.so
, whereas on MS Windows C Library is provided by Visual C runtime file msvcrt.dll
.
After some digging, the following explanation makes the most sense to me:
short version
a header file contains declarations that the compiler needs, but not implementations. The corresponding library file has those. The compiler needs the header files but not the libraries; the linker needs the libraries, not the header files.
long version
The header file does not contain the definition of the printf()
function (ie, its implementation.) That is contained in the C Standard I/O Library (ie, glibc
). The compiler is not able to create the machine instructions that will cause the printf()
function to run, because it does not know where the printf()
implementation is; it cannot create a call to this function. Instead, the compiler places a notation in the executable file that says, more or less, the call to printf()
must be resolved by the linker.
The linker is a separate program that runs after the compiler. It looks at all of the unresolved symbols in the program, such as printf()
, and tries to resolve them by looking up their locations in the software libraries that the program needs. In this case, the linker needs to look up in the C Standard I/O Library the location of the printf()
function, so that it can patch the code to make a call to it ( ldd /usr/bin/gcc
way or gcc -v foo.c -Wl --verbose
way). The C Standard I/O Library is special because it is used in almost every C program, and therefore many C implementations include it within the C runtime library. This makes it possible for the linker to find it easily
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.