Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
182 views
in Technique[技术] by (71.8m points)

c++ - Linker error when including header in files other than main.cpp

I'm trying to add some utility functions and global variables to my code in such a way that I can be able to use them in every class I want in my project. I would like to use a .hpp file for the definitions end a .cpp file for the implementation.

This is a summary of these two files:

// This is Utilities.hpp
#ifndef utilities_hpp
#define utilities_hpp


namespace utils {

    int global_variable1;

    int global_variable2;

    void utility_function1(...);

    void utility_function2(...);

    void utility_function3(...);
}

#endif /* utilities_hpp */

and the implementation:

// This is Utilities.cpp
#include "Utilities.hpp"


namespace utils {

    void utility_function1(...) {
        // Some code
    }


    void utility_function2(...) {
        // Some code
    }


    void utility_function3(...) {
        // Some code
    }

}

Other than my main.cpp file I have two other classes. My main.cpp file includes Class1.hpp header that includes Class2.hpp header.

Now I thought that I could put another #include "Utilities.hpp" in Class1.hpp or Class2.hpp without any problems since I've used the guards in that header. The thing is that when I try to do that the linker throws me this error: Apple Mach-O Linker (ld) Error Group - clang: error: linker command failed with exit code 1 (use -v to see invocation) and I can't understand why or what to do to solve it.

I'm using Xcode 8.3 on a macOS Sierra 10.12.4.

I hope I was able to explain my problem, thank you all very much in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You've violated the One Definition Rule. global_variable1 and global_variable2 should be declared extern in your header and defined in exactly one translation unit (probably Utilities.cpp).

You've defined global variables in a header that gets included in multiple translation units, so there's a utils::global_variable1 defined in main.cpp, and one in Utilities.cpp. When it comes to link time, the linker has no way to know which global_variable1 to use, so it throws an error.

To fix it, add the extern keyword to your declarations and add a definition in "Utilities.cpp":

Utilities.hpp:

// This is Utilities.hpp
#ifndef utilities_hpp
#define utilities_hpp


namespace utils {

    extern int global_variable1;
  //^^^^^^ <-----HERE
    extern int global_variable2;
  //^^^^^^ <-----HERE
    void utility_function1(...);

    void utility_function2(...);

    void utility_function3(...);
}

#endif /* utilities_hpp */

Utilities.cpp:

// This is Utilities.cpp
#include "Utilities.hpp"

namespace utils {

    int global_variable1;  //<---- Definitions added
    int global_variable2;

    void utility_function1(...) {
        // Some code
    }

    void utility_function2(...) {
        // Some code
    }

    void utility_function3(...) {
        // Some code
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...