Jump to content
  • Advertisement
Sign in to follow this  
brainydexter

Link error LNK2005: Already defined

This topic is 3091 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am trying to make a singleton object of this class and when I put this code in the header file, it complains with the "LNK2005: already defined in CollisionMap.obj" I don't understand the meaning of this error in its entirety. I was able to fix the error by putting the code in the corresponding CollisionMap.cpp file. I even have the inclusion guards on, but not sure why this is complaining. I'd like to understand why this is happening. Code:: CollisionMap.h:
#ifndef SPATIALLIB_COLLISIONMAP_H
#define SPATIALLIB_COLLISIONMAP_H

#include "Shape.h"

namespace SpatialLib {

	class CollisionMap
	{
// ...
friend CollisionMap& CollisionMapInstance();

private:
		CollisionMap(void);
		CollisionMap(const CollisionMap& rhs);
};
}

The function CollisionMapInstance() :
CollisionMap& SpatialLib::CollisionMapInstance() {
		static CollisionMap l_collisionMap;
		return l_collisionMap;
	}

If I put this method in the header, it cries. The way I call is, I call this method from multiple places to get hold of the singleton object. Can someone please help me understand what is happening behind the scenes ? Thanks

Share this post


Link to post
Share on other sites
Advertisement
You have to make it inline. Include guards only help if the file is included multiple times *from the same translation unit*. So, if you are in some cpp file and a file gets included twice, include guards will kick in. What's happening is you're compiling two separate source files into OBJ files. Sicne they're separate source files, the function is found twice. Since the function is not inline, a copy of it is made in both object files. When it goes to link, it doesn't know which one to take.


Moral of the story: When writing function bodies in header files that are going to be included from multiple places, make them inline.

Share this post


Link to post
Share on other sites
If I understand correctly, when it links and the same definition is found in two .cpp files, it tries to evaluate that function and gets confused between which one to use later on ?

Also, on the making function "inline", I had a question. I was reading More effective c++ and this is something I just read. It says, not to inline functions that contain local static data. It says due to "internal linkage" from multiple copies of the (non-member) function, there would be more than one copy of the static object in the program. I don't quite understand the whole thing, but I have a feeling that the problem I stated and what the book says are related.

(Pg 134, More Effective c++ by scott meyers )

Thanks for replying though

Share this post


Link to post
Share on other sites
Quote:
Original post by brainydexter
If I understand correctly, when it links and the same definition is found in two .cpp files, it tries to evaluate that function and gets confused between which one to use later on ?

When it's compiling your code it encounters a function with a certain signature. It writes the machine code for this function, as well as its signature into the object file. Later on in another CPP file, same thing happens. When it goes to link, it's tasked with the process of resolving all cross-translation-unit references. For example, maybe in foo.cpp you called some function bar() that was defined in some other source file, but you had the header included so you were able call it. It's at this point that the compiler would say "oh yea, bar(), that comes from xyz.obj".

If the exact same function is defined in two different obj files, then it's stuck because it has two functions with identical signatures and names, both are valid choices for the linking. It could theoretically try to guess that they're the same object code and it doesn't matter, but maybe you had different optimization settings on each file when compiling, or something like that. So there's really nothing it can do except fail.

Quote:

Also, on the making function "inline", I had a question. I was reading More effective c++ and this is something I just read. It says, not to inline functions that contain local static data. It says due to "internal linkage" from multiple copies of the (non-member) function, there would be more than one copy of the static object in the program. I don't quite understand the whole thing, but I have a feeling that the problem I stated and what the book says are related.

(Pg 134, More Effective c++ by scott meyers )

Thanks for replying though


Yes that's a good point. If something is inline then the code is "pulled out" of the function and embedded directly into the source code at the calling point. This means you would be declaring multiple static variables across your code. singletons in general have some pretty serious problems when it comes to multi-threading, but assuming for the sake of simplicity that you just want to get it working, you should just *declare* the funtion in the header file, and then make a new .cpp file where you put the body of the function.
[/source]

Share this post


Link to post
Share on other sites
I feel enlightened :D

Thanks for that insight into the compilation process!

As for inline and that function, that is exactly what I did and it worked with that. I am not sure what problem would occur at multi-threading (possibly state concurrency..i assume which would be a bottleneck for multi-threading apps), but I wont trouble you asking the details of that :D


Thanks again for helping me out.

Share this post


Link to post
Share on other sites
Quote:
Original post by brainydexter
I feel enlightened :D

Thanks for that insight into the compilation process!

As for inline and that function, that is exactly what I did and it worked with that. I am not sure what problem would occur at multi-threading (possibly state concurrency..i assume which would be a bottleneck for multi-threading apps), but I wont trouble you asking the details of that :D


Thanks again for helping me out.


I think it's covered in one of scott meyers' books, perhaps the same one you mentioned earlier. If not you can find out about it on the web, it turns out singletons in general are really really super hard to implement correctly.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!