2

I understand how linking and compiling works when creating .c and .h files and adding them to my project.

But what happens when I add headers like stdio.h to my project? I understand that the linker searches for the .h file in some standard directories, then pastes it in, but the header contains only function prototypes and no code. Where does the compiler or linker find the code for these functions, and how does it get added to my source files?

The reason I ask is because I'm writing a bootloader for a microcontroller and I would like to carefully look through all the C code that's actually getting sent to the compiler. I'm using the non-optimized free version of the XC32 compiler for the PIC32, so I don't trust that it's only including what I'm actually using.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Drew
  • 219
  • 3
  • 15
  • 1
    It's in the libraries. Either standard ones or explicitely linked ones (look at linker settings) – Eugene Sh. Mar 01 '16 at 21:42
  • Possible duplicate question? https://stackoverflow.com/questions/3368121/how-does-a-c-c-compiler-find-the-definitions-of-prototypes-in-header-files – user3303504 Jun 30 '17 at 13:36

2 Answers2

6

You need to distinguish between headers and libraries.

Headers declare facilities that are available to programs. When you include a header such as <stdio.h> (NB: this is not — repeat not! — a library), you make available to the compiler the information necessary to use the facilities from the standard I/O library. In general, C headers do not define the actual code that implements the facilities. C++ has 'header only' libraries (some parts of Boost are prime examples of 'header only' libraries).

Libraries provide the implementation of the facilities. The <stdio.h> header declares a function fopen(); there is a library somewhere that defines that function.

Some headers (actually, typically, it is a lot of headers) are privileged and the facilities that they declare are included in the standard library that the C compiler links your programs with. You don't have to do anything special to get the functions linked into your program. Other headers are from libraries that the C compiler does not know about a priori, and for those, you have to tell it where to find the library (e.g. with -L /opt/sometool/lib as a compiler option) and the library name (e.g. with -lsometool, which might link with /opt/sometool/lib/libsometool.so or /opt/sometool/lib/libsometool.a). Note that the headers for SomeTool are probably in /opt/sometool/include, and you'd need to add an option -I/opt/sometool/include to find the sometool.h header.

The linker doesn't reference headers; the compiler proper doesn't reference libraries. The compiler control program does handle the mixture (it typically runs multiple phases of the compilation process as separate programs — the compiler is separate from the linker). The headers do not contain information about where the library is installed.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
4

The linker does not care at all about header files. The linker doesn't even know these exist as it only ever sees already compiled object files, which is why you explicitly need to specify what libraries to link against with the -l... option. The linker implicitly links in the standard C library (-lc), which is how the standard C functions are found. On many platforms, this does not apply to math functions like sin or pow, which is why you need to link with -lm when you want to use these.

To answer the question where libraries specified to link against with -l... are found: The compiler has a set of standard directories it looks in. It might also look in the working directory. You can add more directories to the library search path with the -L... compiler option. This tells the linker to also look in the specified directory for libraries.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • Some compilers allow `#pragma` directives in the code, which specify the names of libraries to link . (This is either useful or spaghetti, depending on your view!) – M.M Mar 01 '16 at 21:46
  • @M.M Yes. This feature was introduced in Plan 9 if I recall correctly. They built their entire compiler toolchain around this idea, you weren't supposed to ever supply `-L` options to the compiler as you could eliminate them with such a directive. – fuz Mar 01 '16 at 21:47