A code bug already? Please help...

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
primem0ver
Posts: 57
Joined: Sat Oct 11, 2014 11:07 pm

A code bug already? Please help...

Post by primem0ver »

I cannot get my irrlicht program to compile. This is my first time compiling with the C++ version. I am a fairly experienced programmer (in non-professional settings) using Visual Studio 2012 with the Qt plugin. (This is a qt based project). Here is the error:

Code: Select all

error C2535: 'irr::io::xmlChar<T>::xmlChar(wchar_t)' : member function already defined or declared  d:\developing\projects\imt\api\3rd_party\irrlicht-1.8.1\include\irrXML.h
The error appears 3 times. One for each include (my project is VERY compartmentalized because it is plugin based). I have done nothing but include the file and create a basic scene. I have not modified the irrlicht headers in any way.
primem0ver
Posts: 57
Joined: Sat Oct 11, 2014 11:07 pm

Re: A code bug already? Please help...

Post by primem0ver »

Ok... I found the problem. I remember reading somewhere that Qt redefines the wchar_t type as a non-native type (it instead types it as an unsigned short). The line that was causing the problem was this one:

Code: Select all

explicit xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {}
I have changed the above irrlicht .h code to the following:

Code: Select all

#ifndef QGLOBAL_H
        explicit xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {}
#endif
This has resolved the issue in compiling. Does anyone foresee any problems with this?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: A code bug already? Please help...

Post by CuteAlien »

This sounds very wrong. You don't add random defines in library headers. But can't help without knowing anything about your code. Try to start with the examples coming with Irrlicht as first step. Once those compile you know the engine works basically and you can go on working on own projects then.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
primem0ver
Posts: 57
Joined: Sat Oct 11, 2014 11:07 pm

Re: A code bug already? Please help...

Post by primem0ver »

CuteAlien wrote:This sounds very wrong. You don't add random defines in library headers. But can't help without knowing anything about your code. Try to start with the examples coming with Irrlicht as first step. Once those compile you know the engine works basically and you can go on working on own projects then.
Your suggestion is irrelevant for four reasons.
  1. I didn't add a random define to the header. I added a check to see if a define exists from a Qt header. If I don't mix the Qt library with this header, the code will behave normally.
  2. I really don't think you understand the problem. The problem isn't in my code. I am not a beginning programmer but I am just beginning with Irrlicht. I know the engine code works fine by the mere fact that no one else has reported such an obvious bug. (I found that the ONLY reports that even remotely look similar date from 2003). So there had to be another explanation (which I have found).
  3. My use of Irrlicht so far is very basic. The only thing I have done is create a device, grab the scene manager and the driver, and paint a scene with no objects. I haven't even used the xml classes where the error is occurring. This is an "out of the box" attempt with no bells or whistles other than the fact that it is being combined with Qt.
  4. I already know that if I compile the code using irrlicht's examples the code will work just fine. Because they don't Qt.. I also know that if I compiled my own code without using Qt, it will compile just fine.. The problem is that I am using Qt with Irrlicht and it is not my own build of Qt (which some people who have developed qt examples have done). It is a build of Qt specifically to be used with MS VIsual Studio 2012.
Let me be more detailed about the issue so that hopefully you can understand the nature of the problem... (because it is a fairly simple issue to understand for an experienced programmer.)

Here is the part of the original code from Irrlicht header (irrXML.h) we are concerned with. (With some comments added by me to point out the issue).

Code: Select all

 
    struct xmlChar
    {
        T c;
        xmlChar<T>() {}
        xmlChar<T>(char in) : c(static_cast<T>(in)) {}
        xmlChar<T>(wchar_t in) : c(static_cast<T>(in)) {} // NOTICE the wchar_t version here
#if defined(__BORLANDC__)
        // Note - removing explicit for borland was to get it to even compile.
        // There haven't been any kind of tests for that besides that.
        xmlChar<T>(unsigned char in) : c(static_cast<T>(in)) {}
        xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {}
        xmlChar<T>(unsigned int in) : c(static_cast<T>(in)) {}
        xmlChar<T>(unsigned long in) : c(static_cast<T>(in)) {}
#else 
        explicit xmlChar<T>(unsigned char in) : c(static_cast<T>(in)) {}
        explicit xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {} //THIS LINE causes the compile error
        explicit xmlChar<T>(unsigned int in) : c(static_cast<T>(in)) {}
        explicit xmlChar<T>(unsigned long in) : c(static_cast<T>(in)) {}
#endif
        operator T() const { return c; }
        void operator=(int t) { c=static_cast<T>(t); }
    };
 
NOW... the problem is that my build of Qt forces Visual Studio to compile the code with wchar_t redefined as an unsigned short. This is why my error occurs. Others using Qt with other libraries have run into the same problem. See this post in the Ogre3D forum for example.

Since this is the case, I only have a three options:
  1. Build my own version of Qt.
  2. Use the solution suggested in the above post in the Ogre3D forum. Or...
  3. Put a conditional in the above header that compensates for the problem.
I like the third option because it is the most simple. However, in reality... my previous solution does have a problem. I chose the wrong type to put the condition around since it would not allow any unsigned shorts to be handled at all. The solution presented below however shouldn't cause any problems since native wchar_t's are never encountered in a Qt application using my build. When I use another build, I will naturally not use this modified header. But since that will be on a different machine/OS, it won't matter.

Code: Select all

 
struct xmlChar
    {
        T c;
        xmlChar<T>() {}
        xmlChar<T>(char in) : c(static_cast<T>(in)) {}
#ifndef QGLOBAL_H
        xmlChar<T>(wchar_t in) : c(static_cast<T>(in)) {} // prevents wchar_t use in Qt ONLY!!!
#endif
#if defined(__BORLANDC__)
        // Note - removing explicit for borland was to get it to even compile.
        // There haven't been any kind of tests for that besides that.
        xmlChar<T>(unsigned char in) : c(static_cast<T>(in)) {}
        xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {}
        xmlChar<T>(unsigned int in) : c(static_cast<T>(in)) {}
        xmlChar<T>(unsigned long in) : c(static_cast<T>(in)) {}
#else 
        explicit xmlChar<T>(unsigned char in) : c(static_cast<T>(in)) {}
        explicit xmlChar<T>(unsigned short in) : c(static_cast<T>(in)) {}
        explicit xmlChar<T>(unsigned int in) : c(static_cast<T>(in)) {}
        explicit xmlChar<T>(unsigned long in) : c(static_cast<T>(in)) {}
#endif
        operator T() const { return c; }
        void operator=(int t) { c=static_cast<T>(t); }
    };
 
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: A code bug already? Please help...

Post by CuteAlien »

Interesting problem, but I guess you misunderstood me. The wrong part is not about adding some kind of check - but adding a check for one library in a header of another. That's kind of random as it would connect completely independent libraries to each other by sharing defines. Just not something that should ever be done.

Now it's a little bit tricky to find a good solution for this. The nicest one would be to figure out at compile-time already if unsigned short is identical to wchar_t somehow and then exclude it. Not sure if that's possible. The other one would likely be adding a define in Irrlicht which allows re-defining wchar_t the same way as qt (or cmake) seem to do in this case and exclude the line when that define is used. But that would not be default - so you'd never get around recompiling one of the libs.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
primem0ver
Posts: 57
Joined: Sat Oct 11, 2014 11:07 pm

Re: A code bug already? Please help...

Post by primem0ver »

CuteAlien wrote:Interesting problem, but I guess you misunderstood me. The wrong part is not about adding some kind of check - but adding a check for one library in a header of another. That's kind of random as it would connect completely independent libraries to each other by sharing defines.
But... it isn't sharing defines. It is only checking to see if a define exists. If the define doesn't exist, then the compiler interprets the #ifndef as if it doesn't exist...

I know that if I use the same header in another version of qt mixed with irrlicht for a different operating system build it would create a problem. (Indeed... if I build my own project in another OS... or using a non MS VS build... I would have a problem). But I don't have to do that. I can use the original header in another OS.
CuteAlien wrote:Just not something that should ever be done.
No... not if you want the solution to be portable. But I don't need it to be.
CuteAlien wrote:The nicest one would be to figure out at compile-time already if unsigned short is identical to wchar_t somehow and then exclude it. Not sure if that's possible. The other one would likely be adding a define in Irrlicht which allows re-defining wchar_t the same way as qt (or cmake) seem to do in this case and exclude the line when that define is used. But that would not be default - so you'd never get around recompiling one of the libs.
Effectively... this is what I have done, albeit in a non-portable way.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: A code bug already? Please help...

Post by CuteAlien »

I found a clean way already. Testing it currently (not yet checked in as Idid run into another bug while testing it, seems tests haven't been run with VS for a while).

That check should do it correctly I think:
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)

edit: Note that newer qt versions according to what I found on the web are no longer compiled without native char and Visual Studio recommends not using that already for half a decade or so.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: A code bug already? Please help...

Post by CuteAlien »

Irrlicht svn version r4966 allows compiling Irrlicht without native wchar_t.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
primem0ver
Posts: 57
Joined: Sat Oct 11, 2014 11:07 pm

Re: A code bug already? Please help...

Post by primem0ver »

Wow... great suggestion. Thanks! When/if the solution is solidified, I will probably change the name of this thread so that people looking for the specific issue can more easily find the thread by title.
Post Reply