1
votes

The #include directive will result in placing the content of the header file in the source code before compilation : for example if I included stdio.h , the preprocessor will work on placing all the content of stdio.h in the source code then compile isn't it ?

So let's pretend that I'm just using the printf() function in my code. So there must be something that will happen after the compilation and between the linking that will delete all function implementations that were included from the header file and only insert the printf() function implementation in the Import table of the executable , knowing that all other functions were compiled with the source. Can you explain that to me please ?

3
It's not that the other functions are deleted. If you don't call a function, no code is generated that references it, so the linkage is missing by virtue of never having been created. It's like saying "The phone company sent me a phone book. I looked up my friend and called him. When I get my phone bill, I see only my friend listed on the bill. Who deletes all the phone numbers I didn't call?"Raymond Chen
@RaymondChen, not exactly. link-time optimization will eliminate unused code on a per-object-file basis. As for your example, the phone bill may actually contain records for all family members.liuyu
@liuyu The issue here is not linker cleanup. There is nothing to clean up since it was never created.Raymond Chen
There are (usually) no function calls in header files - just the declarations of the signatures (return types, parameter types, and function names) of functions (along with structures, constants, etc.).twalberg
@RaymondChen, you are assuming linkage against shared libraries, where the executable only contains references to the function implementations. But the question is better explained with static linking, i.e., how the linker deals with functions declared in <stdio.h> but not called in the program.liuyu

3 Answers

3
votes

The printf function is not actually in the header file, it's in a library that is automatically linked to the executable by the linker.

Header files should contain only function prototypes, i.e. the declaration of the functions and not the definitions. And as there's no function definitions in the header file, no code will actually be generated for them, and the compiler will make sure that only the functions you actually call will get an entry in the generated object file so the linker knows about it.

1
votes

A function prototype declared in a C header file acts as a compile-time constraint. It identifies the correct number of parameters and correct types of those parameters. The verification of such constraints happens during the compilation phase (i.e. *.c -> *.o).

The (static) linking phase eliminates unused binary objects from programming libraries on a per-object-file basis. A programming library is an archive of binary object files (*.o), each containing the implementation of a collection of functions, constants, etc. As for your question, the binary object file containing the implementation of printf (and everything else in the same object file) will be linked into your program. Other unused object files will be eliminated as a link-time optimization.

0
votes

The header file only contains a declaration, e.g. of the form

size_t printf(char const *format, ...);

This tells the compiler that if it encounters the word printf and it is used as a function, then it can generate a function call.

The call instruction contains a placeholder for the actual address of the function, which is then inserted by the linker when building the final executable.

The linker generally just keeps a running list of yet unresolved symbols, and adds to this list when it encounters one of these placeholders, and fills in the actual address when it finds a definition for the symbol. In the case of printf, that definition is found in the C standard library, so the linker ensures that the library is loaded at runtime and the call instructions point at the right address.