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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With