multiple definition linker error after adding a function to a previously linking file
Asked Answered
D

1

10

So my program is working fine. Compiling, linking, running, the works. Then, I decide to add a simple function to one of my files, like this:

#ifndef UTILITY_HPP
#define UTILITY_HPP

/* #includes here.  There's no circular include, I've checked. */

namespace yarl
{
    namespace utility
    {
        (several function declarations and definitions)

        bool isVowel(const char c)
        {
            if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
                return true;
            else return false;
        }
    }
}

#endif

That function definition is the only change I've made to my code. Everything else is exactly the same as it was. Nothing calls it yet. I compile, and it fails to link, with g++ giving one of these errors for every file that #includes this one:

./obj/Feature.o: In function `yarl::utility::isVowel(char)':
/home/max/Desktop/Development/Yarl Backup/yarl v0.27/src/Utility.hpp:130: multiple     definition of `yarl::utility::isVowel(char)'
./obj/Events.o:/home/max/Desktop/Development/Yarl Backup/yarl v0.27/src    /Utility.hpp:130: first defined here
./obj/GameData.o: In function `yarl::utility::isVowel(char)':

If I comment out isVowel, it works again. I've tried renaming it, still doesn't work. I've tried replacing it with just void randomFunctionName() {}, still doesn't work. I've tried making it non-inline and putting the function body in Utility.cpp, still doesn't work. I am extremely confused. Why would adding one simple function screw up the linker?

Dethrone answered 28/6, 2010 at 22:29 Comment(0)
P
22

Either declare the function inline, or define it in a separate .cpp file. Otherwise every C++ file in which you include the header is trying to make its own, publicly-available definition of the function.

Edit: and fwiw, you don't need to explicitly return true or false if you're testing a conditional. Just return the conditional itself:

inline bool isVowel(const char c)
{
    return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
Pessimist answered 28/6, 2010 at 22:32 Comment(3)
if you mean declaring it as inline bool isVowel(const char c), I tried that, and no dice. I've also tried putting the definition in the implementation file, and still doesn't work.Dethrone
Assuming you didn't make any mistakes when you tried those two things, then maybe you ARE duplicating isVowel. Have you done a global search through all your sources?Pessimist
Scratch that. It didn't work previously because when I recompiled it the makefile didn't recompile the header. Deleting all the object files and recompiling made it notice the inline declaration. Thanks for your help.Dethrone

© 2022 - 2024 — McMap. All rights reserved.