Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Header file included only once in entire program?

I know this is a common question but I still can't fully get my head around it.

In a C or C++ program generated from multiple different source and header files, will each header file be only included once in the entire code when the header guards are used?

Someone told me previously that a header file (with include guards) will get included only once in one translation unit but multiple times in the entire code. Is this true?

If it gets included only once throughout the entire code, when one file wishes to include it and the preprocessor detects that it has already been included, how does that file that wishes to use it know whereabouts in the code it was previously included ?

like image 739
Engineer999 Avatar asked Jun 16 '15 16:06

Engineer999


People also ask

Can you use header files twice in a program?

If a header file happens to be included twice, the compiler will process its contents twice. This is very likely to cause an error, e.g. when the compiler sees the same structure definition twice. Even if it does not, it will certainly waste time.

How do I get header file only once?

The line following #ifndef defines MYCLASS_H_ _ , so if this file is scanned by the preprocessor twice in the same compilation, the second time MYCLASS_H_ _ is defined. By placing all of your code in between the #ifndef and #endif , you ensure that it is only read once during the compilation process.

How can you make a header file not to include multiple times?

To avoid multiple inclusions of the same header file we use the #ifndef, #define and #endif preprocessor directives. Just write the entire program in only file and include headers once only.

Can I include one header file in another?

When header files are protected against multiple inclusion by the #ifndef trick, then header files can include other files to get the declarations and definitions they need, and no errors will arise because one file forgot to (or didn't know that it had to) include one header before another, and no multiple-definition ...


2 Answers

This is the process:

source           header   source header header    \           /        \   |      /   /     \         /          \  |     /   /   PREPROCESSOR            PREPROCESSOR        |                      |        V                      V  preprocessed code      preprocessed code        |                      |     COMPILER               COMPILER        |                      |        V                      V   object code              object code              \            /               \          /                \        /                  LINKER                    |                     V                executable 

Preprocessing

#include is for this first step. It instructs the preprocessor to processes the specified file, and insert the result into the output.

If A includes B and C, and B includes C, the preprocessor's output for A will include the processed text of C twice.

This is a problem, since it will result in duplicate declarations. A remedy is to use preprocessor variables track whether the source code has been included (aka header guards).

#ifndef EXAMPLE_H #define EXAMPLE_H  // header contents  #endif 

The first time, EXAMPLE_H is undefined, and the preprocessor will evaluate the contents within the ifndef/endif block. The second time, it will skip that block. So the processed output changes, and the definitions are included only once.

This is so common that there is a non-standard directive implemented by some compilers that is shorter and does not require choosing a unique preprocessor variable:

#pragma once  // header contents 

You can figure out how portable you want your C/C++ code, and which header guard to use.

Headers guards will ensure the contents of each header file are present at most once in the preprocessed code for a translation unit.

Compiling

The compiler generates machine code from your preprocessed C/C++.

Generally, the header files only include declarations, not the actual definitions (aka implementations). The compiler includes a symbol table for anything that is currently missing an definition.

Linking

The linker combines the object files. It matches up the definitions (aka implementations) with the references to the symbol table.

It may be that two object files provide the definition, and the linker will take one. This happens if you've put executable code in your headers. This generally does not happen in C, but it happens very frequently in C++, because of templates.

The header "code", whether declarations or definitions, is included multiple times across all object files but the linker merges all of that together, so that it is only present once in the executable. (I'm excluding inlined functions, which are present multiple times.)

like image 160
Paul Draper Avatar answered Sep 29 '22 09:09

Paul Draper


A "header file" is actually inserted by the pre-processor before compilation starts. Just think of it as just "replacing" its #include directive.

The guard ...

#ifndef MY_HEADER_H #define MY_HEADER_H  ....  #endif 

... is executed after the replacement. So, the header may actually be included multiple times, but the "guarded" part of the text is only passed to the compiler once by the preprocessor.

So, if there are any code-generation definitions in the header, they will - of course - be included into the object file of the compilation unit (aka "module"). If the same header is #includeded in multiple modules, these will appear multiple times.

For static definitions, this is no problem at all, as these will not be visible beyond the module (aka file scope). For program-global definitions, that is different and will result in "multiple definitions" error.

Note: this is mostly for C. For C++, there are significant differences, as classes, etc. add additional complexity to what/when multiple global objects are allowed.

like image 44
too honest for this site Avatar answered Sep 29 '22 09:09

too honest for this site