简体   繁体   中英

Where the compiler find ``printf``?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM