Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

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

1 Answer

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
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...