Doubt about compilation in C/C++

Asked

Viewed 358 times

2

I started studying the compilation of multiple files and I had a question. When we create a new header, we have to create another file with the implementation of the prototypes contained in the header, create the object and compile everything together. However, when we include standard libraries, such as stdio.h, We don’t need to create his object file or compile it together. Why and how is this done?? Functions are already implemented within these standard libraries?

From now on, thank you.

2 answers

3

TL/DR: Your compiler / linkeditor is finding the dependencies you included (e. g., stdlib.h) in some library in the default path. According to compile/ linkedit options, the library is being included dynamically or statically.

Your question has a simple answer, but it is not possible to talk about what happens without reviewing a number of concepts:

Dynamic vs static libraries

C / C++ libraries can be statically or dynamically linked.

In a coarse simplification, static linkediting produces an independent executable with a copy of the library; that is, you end up with a larger executable containing the binary of your application and the library. If you need to change the library you will have to recompile your application to include the new changes.

In contrast, dynamic linkediting produces independent artifacts. A shared library (usually .so in systems *NIX and .dll in Windows) is press load time or run time. Roughly the application that references a dynamic library contains a "symbol table" indicating external dependencies, when any of these dependencies (e.g., any function) is requested it is "loaded in memory" (the details of the "algorithm" that determines how and which library should be "loaded" are complex, I don’t want to get into that merit).

The advantage of dynamic libraries is that a single library can be shared between multiple executables; additionally libraries can also be upgraded independently (provided binary compatibility is maintained). The downside is that complex projects can end up with a deep dependency graph, creating all kinds of problems (version incompatibility, accidental inclusion of legacy library versions, need to do backport of cool security for legacy versions, etc, etc, etc).

Templates

In addition to prototypes of functions, structs, classes and enumerations (part of the "signature / interface" of a given library), templates are included in the headers. At compile time / linkediting specific versions of the parameterized constructions are generated (e.g., a version with int and another with float of a function template) embedded in the application binary. That’s why in some compilers the size of the binary grows significantly when you use, for example, the Std.

How linkeditor finds a library

How does your linkeditor find a library? Roughly it does a search on path (path) where libraries are available. The answer from @pmg mentions the libc; linkeditor can find an implementation like libc.so or msvcrt.lib in a multitude of places by a multitude of rules (flags passed to the linkeditor, environment variables such as LD_LIBRARY_PATH, standard directories as /usr/lib, current application directory, etc, etc, etc.). The rules usually vary with the operating system and the stack of build.

So what really happens when I include libraries like stdlib.h, iostream, etc.?

In sufficiently complex applications, the required libraries are localized and there is a combination of dynamic and static linkage as well as instantiation / template expansion. While most compilers will, by default, do their best to dynamically link libraries, a portion of the library code ends up being directly or indirectly copied / expanded within the executable.

Linkeditors are usually able to report everything that has been statically and dynamically linked (e. g., gcc -Wl --verbose). Additionally, tools such as ldd and Dependency Walker can list dependencies.

1

The compilation of functions that have prototypes, for example, in <stdio.h> was made by someone else on another computer. This person put these compiled objects into a library and when you installed your Operating System (or compiler) you also installed that library. The library in question is called "libc" and, if you say nothing to the contrary when compiling a program your compiling automatically includes that library.

Note that this same library has the result of compiling many other functions besides those that have prototype in <stdio.h>.

For historical reasons, functions with prototype in <math.h> not usually add to library libc, but the library libm. Some compilers do not search the library libm when compiling, therefore, for these compilers, 'it is necessary to indicate that library

gcc main.c -lm

The -l gcc invocation, tells the compiler to search in the specified library, preceded by "lib".

Browser other questions tagged

You are not signed in. Login or sign up in order to post.