Why it's valid to include a header file twice in c++?

后端 未结 7 881
迷失自我
迷失自我 2021-02-09 17:25
#include \"DLLDefines.h\"
#include \"DLLDefines.h\"

The above actually passed compilation, but why?

7条回答
  •  名媛妹妹
    2021-02-09 18:11

    Well, it's legal because it has to be legal. Because you often include the same header multiple times without even realizing it.

    You might include two headers in a .cpp file, each of which include a number of files, some of which might be included by both.

    For example, all the standard library headers (say, string or vector for example) are probably included in most of your headers. So you quickly end up with the same header being indirectly included multiple times in the same .cpp file.

    So in short, it has to work, or all C++ code would fall apart.

    As for how it works, usually through include guards. Remember that #include just performs a simple copy/paste: it inserts the contents of the header file at the #include site.

    So let's say you have a header file header.h with the following contents:

    class MyClass {};
    

    now let's create a cpp file which includes it twice:

    #include "header.h"
    #include "header.h"
    

    the preprocessor expands this to:

    class MyClass {};
    class MyClass {};
    

    which obviously causes an error: the same class is defined twice. So that doesn't work. Instead, let's modify the header to contain include guards:

    #ifndef HEADER_H
    #define HEADER_H
    
    class MyClass {};
    
    #endif
    

    Now, if we include it twice, we get this:

    #ifndef HEADER_H
    #define HEADER_H
    
    class MyClass {};
    
    #endif
    
    #ifndef HEADER_H
    #define HEADER_H
    
    class MyClass {};
    
    #endif
    

    And this is what happens when the preprocessor processes it:

    #ifndef HEADER_H // HEADER_H is not defined, so we enter the "if" block
    #define HEADER_H // HEADER_H is now defined
    
    class MyClass {};// MyClass is now defined
    
    #endif           // leaving the "if" block
    
    #ifndef HEADER_H // HEADER_H *is* defined, so we do *not* enter the "if" block
    //#define HEADER_H
    //
    //class MyClass {};
    //
    #endif           // end of the skipped "if" block
    

    So, the end result is that MyClass got defined only once, even though the header was included twice. And so the resulting code is valid.

    This is an important property of header files. Always define your headers so that it is valid to include them multiple times.

提交回复
热议问题