Alex Rivera | Logout

error LNK2005: already defined - C++

Asked 2009-03-07T18:05:48.480
16

Background

I have a project named PersonLibrary which has two files.

  1. Person.h
  2. Person.cpp

This library produces a static library file. Another project is TestProject which uses the PersonLibrary (Added though project dependencies in VS008). Everything worked fine until I added a non-member function to Person.h. Person.h looks like

class Person
{
public:
    void SetName(const std::string name);

private:
    std::string personName_;
};

void SetPersonName(Person& person,const std::string name)
{
    person.SetName(name);
}

Person.cpp defines SetName function. When I try to use SetPersonName from TestProject, I get error LNK2005: already defined. Here is how I used it

#include "../PersonLibrary/Person.h"
int main(int argc, char* argv[])
{
    Person person;
    SetPersonName(person, "Bill");
    return 0;
}

Workarounds tried

1 - I have removed the Person.cpp and defined the whole class in Person.h. Error gone and everything worked.

2 - Changed the SetPersonName modifier to static. Like the below

static void SetPersonName(Person& person,const std::string name)
{
    person.SetName(name);
}

Questions

  1. Why the code shown first is not working as I expected?
  2. What difference static made here?
  3. What is the approapriate solution for this problem?

Thanks

Edit
Report

1 Answer

3

When you compile you're library, its lib file contains a definition for SetPersonName. When you compile your program that uses the library, since it includes the header, and you've written the code inline in the header it also compiles in a definition for SetPersonName. Two definitions for the same function aren't (generally) allowed. The static keyword tells the compiler that the function shouldn't be exposed outside of the current translation unit (discrete piece of code you are compiling), so the definition in the library isn't visible to the linker.

The appropriate solution to this problem depends on your goals. Header files with static function declarations is almost never what you want. From a design standpoint I would recommend getting rid of SetPersonName altogether, and just use Person::SetName.

However, failing that, I would implement it much like you've done for the rest of your functionality, declarations in the header, and implementation in the .cpp. Inline functions associated with a library will tend to diminish many of the advantages of using a library in the first place.

answered 2009-03-07T18:22:04.353

Your Answer