Search code examples
c++one-definition-ruleinline-functions

One header file in multipe cpp files: Multiple definition


I am trying to access one header file in multiple C++ files. The header file is defined as follows:

#ifndef UTILS
#define UTILS

void toUpper(string &str) {
    for(unsigned int i=0; i<str.length(); i++) {
            str.at(i) = toupper(str.at(i));
    }
}

void toLower(string &str) {
    for(unsigned int i=0; i<str.length(); i++) {
            str.at(i) = tolower(str.at(i));
    }
}


#endif // UTILS

When I compile the code I get the following error: enter image description here

As far as I know, this should not return multiple definitions since I am restricting the code from being defined more than once. I also tried using the precompiled directive "#pragma once"


Solution

  • There are 2 solutions to this problem.

    Solution 1

    You can add the keyword inline infront of the function like:

    myfile.h

    #ifndef UTILS
    #define UTILS
    
    inline void toUpper(string &str) {
        for(unsigned int i=0; i<str.length(); i++) {
                str.at(i) = toupper(str.at(i));
        }
    }
    
    inline void toLower(string &str) {
        for(unsigned int i=0; i<str.length(); i++) {
                str.at(i) = tolower(str.at(i));
        }
    }
    
    
    #endif // UTILS
    
    

    Now you can include this header in different files without getting the mentioned error.

    Solution 2

    You can create a separate .cpp file and put the definition there. This would look like:

    myfile.h

    #ifndef UTILS
    #define UTILS
    
    //just declarations here
    void toUpper(string &str);    //note no inline keyword needed here
    
    void toLower(string &str);    //note no inline keyword needed here
    
    #endif // UTILS
    
    

    myfile.cpp

    #include "myheader.h"
    void toUpper(string &str) {
        for(unsigned int i=0; i<str.length(); i++) {
                str.at(i) = toupper(str.at(i));
        }
    }
    
    void toLower(string &str) {
        for(unsigned int i=0; i<str.length(); i++) {
                str.at(i) = tolower(str.at(i));
        }
    }