GLM library, unresolved symbol

Hello,
I use the GLM math library in my opengl applications.
When I store an Object into a stl::map that has members
of types from GLM like glm::vec3 then I get an error for
an unresolved external symbol.

Please have a look at this piece of code


class CFoo
{
   private:
     glm::vec3 abc;
   public:
     ....
}
...
map<string, CFoo*> FooMap;
map<string, CFoo*>::iterator It = FooMap.find("a_Foo");
if(It != FooMap.end())  <---- this line causes the error
{
   ...
}

The if statement causes the unresolved external symbol error.
unresolved external symbol “bool __cdecl glm::gtx::comparison::operator!=…”

But when I use a const_iterator the error does not appear.
Did anyone has the same problem with it ?

In some cases I cant use a const iterator, e.g. removing objects from a map.
any ideas ?

regards,
lobbel

That’s a strange problem…

I tried to reproduce the problem with Visual Studio 2010 and GLM 0.9.0.5 but I haven’t been successful.

Which compiler do you use and which version of GLM do you use?

if(It != FooMap.end()) <---- this line causes the error

Nope, sorry; I don’t buy it.

Iterator comparison, even std::map iterators, does not do deep comparisons. It does not compare the objects contained in the container. And even if it could (and it doesn’t), it wouldn’t be able to do deep comparisons with the .second values (Foo*) because it’s a Foo* and not a Foo object. It would compare the pointers. The only way for that to be a deep comparison is if you overloaded the comparison operators for Foo*/Foo* comparisons.

Which again, even if you did, doesn’t get around the fact that iterator comparison doesn’t compare the contents of the iterators.

Something else is going on here.

On the other hand, GLM is a header-only library so it is pretty unsure that it produces a link error, unless something gone really wrong in how you use it.

Hello,

I made a test project with visual studio 2005 and I can reproduce the error.

here is the code


// OglForum.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <map>
#include <utility>
#include <string>
#include "glm\glm.hpp"
#include "glm\ext.hpp"

using namespace std;


class Foo
{
	protected:
		glm::vec3 a;
		glm::vec3 b;
		glm::vec3 c;
	public:
		Foo(){}
};

int _tmain(int argc, _TCHAR* argv[])
{
	map<string, Foo*> foomap;

	foomap.insert(pair<string, Foo*>("A", new Foo));
	foomap.insert(pair<string, Foo*>("B", new Foo));
	foomap.insert(pair<string, Foo*>("C", new Foo));


	map<string, Foo*>::iterator it = foomap.find("A");
	if(it != foomap.end())
	{
		delete it->second;
		foomap.erase(it);
	}

	return 0;
}

And again, the if(it != foomap.end()) is the reason for the error. Further more with the following code I also get this error. The only difference is, that I only included the GLM headers. This seems to be sufficient to cause this error. I dont know why.


// OglForum.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <map>
#include <utility>
#include <string>
#include "glm\glm.hpp"
#include "glm\ext.hpp"

using namespace std;


class Foo
{
	protected:
		//glm::vec3 a;
		//glm::vec3 b;
		//glm::vec3 c;
	public:
		Foo(){}
};

int _tmain(int argc, _TCHAR* argv[])
{
	map<string, Foo*> foomap;

	foomap.insert(pair<string, Foo*>("A", new Foo));
	foomap.insert(pair<string, Foo*>("B", new Foo));
	foomap.insert(pair<string, Foo*>("C", new Foo));


	map<string, Foo*>::iterator it = foomap.find("A");
	if(it != foomap.end())
	{
		delete it->second;
		foomap.erase(it);
	}

	return 0;
}

If I dont include the glm headers everything is ok.

Any ideas ? Did I miss some important work to do when using
stl::map ?

regards,
lobbel

I tried again, with Visual Studio 2005 and the only difference was that I removed “stdafx.h” and the Windows proprietary stuff…

However, I can’t reproduce the problem again…

Hello,
I just tried it with the removed stdafx.h. It’s the same
problem as before. But when I remove the glm\ext.hpp it works.

This works…


#include <map>
#include <utility>
#include <string>
#include "glm\glm.hpp"
//#include "glm\ext.hpp"
...

thanks & regards,
lobbel

Do you have install the Visual Studio 2005 SP1?

Yes, I have. But I also have this problem
with my visual studio 2010.

Using a const_iterator solves the problem, but this one can’t be used for deleting the mapped entry.

Btw: I’m using GLM 9.0.0.1, the other newer version causes
errors with the new data type you added.

regards,
lobbel

Which new types? Oo

Something really odd here.

Hi,
I was talking about version 0.9.0.2 and GLM_GTX_int_10_10_10_2.

I have absolutely no clue why I get this error when including the
ext.hpp.


1>e:\Cpp\OglForum\Debug\OglForum.exe : fatal error LNK1120: 1 unresolved externals
OglForum.obj : error LNK2019: unresolved external symbol "bool __cdecl glm::gtx::comparison::operator!=<class std::_Tree<class std::_Tmap_traits<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Foo *,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class Foo *> >,0> >::iterator>(class std::_Tree<class std::_Tmap_traits<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Foo *,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class Foo *> >,0> >::iterator const &,class std::_Tree<class std::_Tmap_traits<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Foo *,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class Foo *> >,0> >::iterator const &)" (??$?9Viterator@?$_Tree@V?$_Tmap_traits@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVFoo@@U?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVFoo@@@std@@@2@$0A@@std@@@std@@@comparison@gtx@glm@@YA_NABViterator@?$_Tree@V?$_Tmap_traits@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVFoo@@U?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVFoo@@@std@@@2@$0A@@std@@@std@@0@Z) referenced in function _main

regards,
lobbel

My advice would be to include glm/glm.hpp and only the extra features you need instead of glm/ext.hpp which is actually recommended for any GLM users anyway.

That doesn’t fix the problem but it will work for you as long as you don’t include “glm/gtx/comparison.hpp” which is a problem somehow for you.

Hello,
I found “the problem”. It is comparison.hpp and comparison.inl.
There you declare the comparison operator for your datatypes


//! Define != operator for vectors
//! From GLM_GTX_comparison extension.
template <typename vecType>
bool operator!= (vecType const & x, vecType const & y);

And in the inline file you define the operator for all your
types (vec2, vec3 etc).

If I copy the the part for the != operator from the inline file (comparison.inl) to the comparison.hpp and comment out the corresponding code in the inline file then it works.
I dont know why but it is working that way. I had this problem
on two different machinese and both with visual studio 2005 (SP1) and visual 2010 installed.

comparison.hpp


//! Define != operator for vectors
//! From GLM_GTX_comparison extension.
//template <typename vecType>
//bool operator!= (vecType const & x, vecType const & y);
template <typename valType>
inline bool operator!= 
(
	detail::tvec2<valType> const & x, 
	detail::tvec2<valType> const & y
)
{
	return glm::any(glm::notEqual(x, y));
}
...
...
...


I also checked if this “problem” raises when using the == operator with a stl map. But there everything works fine.

Well, it works. May be a unusual solution but I can’t explain
myself the reason for this “problem”.

regards,
lobbel