Linking .h files with .c with #ifdef header guards

前端 未结 4 1985
夕颜
夕颜 2020-12-09 05:09

im having trouble linking .h and .c files, i\'ve also read some threads regarding this problem and all of them is a bit vague and still i can\'t fully grasp the concept of i

4条回答
  •  天涯浪人
    2020-12-09 05:37

    You do indeed need to #include b.h in b.c. Each file is compiled separately before the linker takes over, so it doesn't matter that you have included b.h in a.c, because b.c is compiled by itself and has no idea about the contents of b.h unless you include it.

    Here's an example of a #include guard

    // some_header_file.h
    #ifndef SOME_HEADER_FILE_H
    #define SOME_HEADER_FILE_H
    // your code
    #endif
    

    When some_header_file.h is included anywhere, everything in between the #ifndef and the #endif will be ignored if SOME_HEADER_FILE_H has been defined, which will happen on the first time it is included in the compilation unit.

    It is common practice to name the #define after the name of the file, to ensure uniqueness within your project. I like to prefix it with the name of my project or namespace as well, to reduce the risk of clashes with other code.

    NOTE: The same header file CAN be included multiple times within your project even with the above include guard, it just can't be included twice within the same compilation unit. This is demonstrated as follows:

    // header1.h
    #ifndef HEADER_H
    #define HEADER_H
    int test1 = 1;
    #endif
    
    // header2.h
    #ifndef HEADER_H
    #define HEADER_H
    int test2 = 2;
    #endif
    

    Now let's see what happens when we try to include the above two files. In a single compilation unit:

    // a.cpp
    #include "header1.h"
    #include "header2.h"
    #include 
    int main()
    {
       std::cout << test1;
       std::cout << test2;
    };
    

    This generates a compiler error because test2 is not defined - it is ignored in header2.h because HEADER_H is already defined by the time that is included. Now if we include each header in separate compilation units:

    // a.cpp
    #include "header2.h"
    int getTest2()
    {
       return test2;
    };
    
    // b.cpp
    #include "header1.h"
    #include 
    int getTest2(); // forward declaration
    int main()
    {
       std::cout << test1;
       std::cout << getTest2();
    };
    

    It compiles fine and produces the expected output (1 and 2), even though we are including two files which both define HEADER_H.

提交回复
热议问题