Sahil Arora
Sahil Arora

Reputation: 885

Why do we need to include the C or CPP declaration files during compilation and not the default libraries like iostream?

If a C or CPP program needs to be compiled with our own header files with declarations and cpp files with definitions, we need to include the cpp files with definitions in the compilation command (See this answer). However, when we write #include <iostream>, we do not include iostream.cpp in the compilation statement like g++ main.cpp iostream.cpp -o main.

If we write our custom declaration files, for instance hello.hpp with class declaration and hello.cpp with the definitions, we need to compile it using g++ main.cpp hello.cpp -o main after including hello.hpp in the header in the main.cpp file. Why is this?

EDIT: Is it possible that we can imitate the behavior of the standard template library for our custom header and cpp files such that all we have to do is just include the header and the declarations automatically get compiled? If yes, then how? If no, why not?

Upvotes: 5

Views: 678

Answers (3)

Sam Hobbs
Sam Hobbs

Reputation: 2891

You need to understand that the compiler reads input files, then pre-processes them and the preprocessor replaces all the #include statements so the compiler itself never sees them. As far as the real compiler is concerned, there are no #include statements. The compiler then converts the source language to machine code. There is one object file written by the compiler for every input (c or cpp) file. The machine code in the object files cannot be executed directly; it must be linked with other code.

Originally, programmers would link their programs with other object files that are already compiled into libraries of object files. Multiple object files were linked together statically to make an executable and that might be done for many executables. So in other words each of many object files might exist many times, once for each of many executables. And that means that when something changes, sometimes many programs using the same object files had to be linked again. Later programmers learned that it helps to link to object files dynamically, and that is what a dynamic link library is.

When you compile your program, the compiler includes instructions to the linker to link to other libraries, mainly the "C Runtime" (CRT). The link can be either a static link or a dynamic link. Also, the headers provides information about the CRT. Most of the Standard Libraries (std namespace) are actually in the headers, such as in "iostream" and get compiled with your program. Anything that is not in the header is in a CRT library somewhere.

So the equivalent of what might be a iostream.cpp is either in your own program, such as main.cpp, or has already been compiled and is in a CRT library that is linked with your program.

Upvotes: 1

Mendes
Mendes

Reputation: 18501

First of all, check the difference between including a <filename> and "filename" at this post:

For #include "filename" the preprocessor searches in the same directory as the file containing the directive. This method is normally used to include programmer-defined header files.

For #include < filename> the preprocessor searches in an implementation dependent manner, normally in search directories pre-designated by the compiler/IDE. This method is normally used to include standard library header files

The fact that you are including a file does not mean that you are compiling a file. In fact, by including your are solving the syntax references to the included file, like class declarations (in C++), common variables, structures, enums and funcion calls. This will avoid your code to get unreferenced object errors, breaking the compilation process.

Compiling your code with these references does not mean also that the original referenced code is compiled. Take the example below:

mycode.cpp includes myclass.hpp, as:

#include "myclass.hpp"

If the references are correct, you can compile it using:

g++ mycode.cpp 

You are gonna have a compiled code for mycode.cpp (an object file called mycode.o), but not the compiled code to myclass. The mycode.cpp compiled properly because it has the references to the myclass objects/functions/etc., but this does not mean that the myclass is compiled (you don´t have yet a object file myclass.o).

If you link edit mycode.cpp, there will be several missing references as there is no myclass compiled code.

If you choose:

g++ mycode.cpp myclass.cpp 

It will generate object files for both mycode.o and myclass.o, that later can be linked together.

In case of STL libraries, you just need the reference, as they are already compiled and available though in the so called standard library (a bundle of object .o files already compiled for you). The liker will take care of linking then together either automatically or if you properly tell him to do it.

I suggest you go through the compilation -> object files -> link editing -> executable file process to understand these steps, that happens only to compiled languages.

Upvotes: 2

dlasalle
dlasalle

Reputation: 1725

The standard libraries are being implicitly linked against. So

g++ main.cpp -o main

is really

g++ main.cpp -o main -lstdc++ -lc

where libstdc++ is the c++ standard library, and libc is the c standard library. Other libraries need to be explicitly linked against (such as libm).

This becomes more clear if you separate your compile and linking steps:

g++ -c main.cpp -o main.o
g++ -c other.cpp -o other.o
g++ main.o other.o /usr/lib/libstdc++.a /usr/lib/libc.a -o main

Here we compile our main() function definition and other definitions (other.cpp) into object files, and combine them with the existing compiled function/class/variable definitions in the standard libraries.

See TLDP's pages on Shared Library Creation and Static Library Creation for details on how definition files (.c and .cpp) are turned into libraries.

Upvotes: 6

Related Questions