Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does #include work in C++?

Tags:

c++

include

If a library is included in a class header and then this header is included in another class do I have to include the library again?

For example:

#ifndef A_H
#define A_H

#include<someLibrary.h>

class A{
  ...
}

#endif

Then another class includes the A.h header

#include<A.h>   //include class A
class B{
   ...
}

Do I have to include the "someLibrary.h" in class B?

like image 759
tony Avatar asked Mar 01 '16 10:03

tony


3 Answers

No, #includes are transitive.

However, if your second file itself uses symbols from someLibrary, it's good style to re-include the header. That way you're not "hoping and praying" that you never remove the intermediate include. Your codebase will be more robust if every source file #includes everything that it directly needs. Header guards prevent this from being a wasteful policy.

like image 62
Lightness Races in Orbit Avatar answered Nov 02 '22 01:11

Lightness Races in Orbit


The preprocessor #include directive does exactly what the name implies, it actually includes the file at the place of the directive.

Simple example: Lets say we have to files, first a header file named a.h

// Our class
class A
{
    // Stuff for the class
};
// End of the class

Then a source file a.cpp:

// Include header file
#include "a.h"
// Header file included

int main()
{
    // Code
}

The preprocessor generates a single file looking like

// Include header file
// Our class
class A
{
    // Stuff for the class
};
// End of the class
// Header file included

int main()
{
    // Code
}

This inclusion is recursive, so if a header file is including another header file, that other header file will also be included.

The source file generated by the preprocessor is called a translation unit and is what the compiler actually sees.


The above is a simplification on how a modern preprocessor works, and while it can be run separately to create a preprocessed source file, it's more common that the preprocessor is part of the compiler to streamline the parsing process.


You should also note that the terminology you use is not correct. A library can (and usually do) have one or more header files, which are used when compiling your source code. A library then often (but not always) contain a special library file that is linked with the object files created by the compiler.

A library that has no linker library is called a header only library.

like image 10
Some programmer dude Avatar answered Nov 02 '22 00:11

Some programmer dude


You don't include classes or libraries, you just include headers, and that is a textual operation (a bit like a copy & paste done by the preprocessor).

Read more about the C/C++ preprocessor, and the GNU cpp.

You can ask your compiler to show you the preprocessed form of your source file foo.cc, e.g. with g++ -Wall -C -E foo.cc (it will spills on stdout the preprocessed form)

For a small project (e.g. less than 200KLOC), having just one single common header file included by all your translation units is sensible (and I believe that having many small header files is bad habit, so I usually put more than one class definition per header file). BTW, that (single header file) approach is friendly for precompiled headers. Some people prefer to have several of their own #include-d subheaders in that single header.

Notice that most C++ standard headers (like <map> or <vector>....) bring a lot of text, so you don't want to have tiny compilation units (on my Linux system, #include <vector> is dragging more than ten thousand lines, so having only a few dozen of your source code lines after is inefficient for the compiler)

Also notice that C++ class definitions usually have lots of inlined member functions (and you practically want to give the body of that inlined function in the same header file). So C++ header code tends to be quite big...

(some people prefer to break a single header file in many subheaders, which are always included together)

like image 5
Basile Starynkevitch Avatar answered Nov 02 '22 01:11

Basile Starynkevitch