1

I have a question regarding compilation with GCC.

I have a slight confusion that I believe I've figured out but would like confirmation on. In the first compilation step, preprocessing (cpp) organizes our .c file into a .i file and among other tasks, includes headers in this file.

Then, three steps later, the linker (ld) also handles libraries by adding them to the a.out file.

Initially, I thought both processes were performing the same task redundantly, but now I believe I understand the difference but i would like a confirmation.

My understanding is that cpp only includes library declarations in the .i file, whereas the linker (ld) places the entire code of the stdio.h library in the a.out file.

Could someone please confirm if my understanding is correct?

Thank you for your help!

1 Answer 1

1

In the first compilation step, preprocessing (cpp) organizes our .c file into a .i file and among other tasks, includes headers in this file.

That is what logically happens as the first step, yes. In the dawn of time there was a separate program cpp, which performed this step.

But currently this step is logical-only, no production compiler actually generates the .i file, unless you ask it to. Instead, preprocessing feeds directly into the later stages of the compiler, producing assembly (.s) output. This arrangement is called "integrated preprocessor".

Similarly, the next step: .s -> .o transformation is bypassed by some compilers (this is called "integrated assembler"), while other compilers do invoke the as (assembler) to perform this step as a separate process.

My understanding is that cpp only includes library declarations in the .i file

It includes whatever is contained in the header file. It could be declarations, but it could also be definitions of functions and/or variables.

whereas the linker (ld) places the entire code of the stdio.h library in the a.out file.

On most UNIX systems there is no such thing as "stdio.h library". Rather stdio.h is provided by the system libc (of which there are several implementations).

In addition, "places entire code of the library in the a.out" is incorrect in several aspects:

  • only the referenced parts of the library are included (not the entire library) in the case of using archive libc.a
  • something else entirely happens when linking with libc.so (which is the default).

P.S. You can actually see what happens for yourself, there is no need to guess.

Create a trivial libfoo.a library, reference the header for that library in main.c, use gcc -E main.c > main.i to observe what ends up in the .i file, and objdump -d a.out to observe what happens with the code in libfoo.a during linking.

Extend this exercise to put the same code into libfoo.so, link with it, and observe how the picture changes.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.