By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,434 Members | 1,878 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,434 IT Pros & Developers. It's quick & easy.

Porting from MSVC to GCC, vague errors

P: 12
As the title says, I am porting some code from MSVC (not sure which version, using Visual Studio 2008), which compiles without errors or warnings, to GCC 4.0 which generates a large number of generic errors.

The project uses a large header file 'precompiled.h' which includes two other header files, math/math.h and math/vector.h in that order. I've already disabled the ALWAYS_SEARCH_USER_PATHS which was causing other errors.

From math/math.h

Expand|Select|Wrap|Line Numbers
  1. class qMath {
  2. public:
  3. ...
    static float Fabs( float x );
    ...
  4. };
  5.  
  6. inline float qMath::Fabs( float x ) {
  7. ...
    return x;
    }
  8.  
From math/vector.h

Expand|Select|Wrap|Line Numbers
  1. inline bool qVec2::Compare( const qVec2 &a, const float epsilon ) {
  2. // the following is line 106
    ( qMath::Fabs( x - a.x ) > epsilon )
    ...
Which generates the following errors:

../math/Vector.h:106: error: 'qMath' has not been declared
../math/Vector.h:106: error: 'Fabs' was not declared in this scope

And the same sort of errors wherever qMath is referenced.

Been mucking around with this for awhile now and haven't gotten anywhere, any help would be appreciated.
Nov 10 '08 #1
Share this Question
Share on Google+
17 Replies


boxfish
Expert 100+
P: 469
I doubt I can be of any help with this, but maybe you could post your makefile? It sounds like a problem with either your includes or your makefile.
Nov 11 '08 #2

P: 12
I'm using Xcode as my development environment and I'm not sure where exactly to view the makefile. It fails while trying to create the precompiled header object /precompiled.h.gch, which is the first object being compiled.

By using the -H compiler flag I can see that the headers are being added in the correct order, and errors are not generated until after all the headers have been included. Since this the code compiles without errors in MSVC I'm assuming it's something specific with GCC.
Nov 11 '08 #3

boxfish
Expert 100+
P: 469
Okay, I see, sorry. I had thought you were just using a text editor, writing the makefiles by hand, and running gcc from the shell.
Nov 11 '08 #4

Banfa
Expert Mod 5K+
P: 8,916
Is there a namespace declared in Math.h containing qMath? If so then

qMath::Fabs

needs to be

<NameSpace>::qMath::Fabs

It is less likely to be something specific with GCC so much as some wired MS extension causing the code to compile when it shouldn't.
Nov 11 '08 #5

P: 12
Not using any namespace declarations.
Nov 11 '08 #6

P: 12
If it is because of MS specific extensions it is near impossible for me to tell which or why since disabling their extensions prevents even their standard header files from compiling.
Nov 11 '08 #7

Banfa
Expert Mod 5K+
P: 8,916
Yes I know quite irritating isn't it :7

Hmmm, given what we can see of your code all I can say is that for some reason (when using GCC) at the time that vector.h is parsed the declarations in Math.h have not been parsed so the compiler does not know about qMath (Vector.h isn't included into Math.h is it?).

You can test this by forward declaring qMath
class qMath;
at the top of vector.h, this will not solve the problem but it should give different errors (incomplete type).
Nov 11 '08 #8

P: 12
Yes I know quite irritating isn't it :7

Hmmm, given what we can see of your code all I can say is that for some reason (when using GCC) at the time that vector.h is parsed the declarations in Math.h have not been parsed so the compiler does not know about qMath (Vector.h isn't included into Math.h is it?).

You can test this by forward declaring qMath
class qMath;
at the top of vector.h, this will not solve the problem but it should give different errors (incomplete type).
That is what I suspected even though, as I said, the headers are included in the correct order. I've actually already tried forward declaring qMath which generates the incomplete type errors you predicted. I'm about at wit's end trying to understand what could be wrong here.

I suppose it interesting that the error that I get about qMath is slightly different than those generated by other unrecognized symbols, I'm not sure if this is just because it is interpreted as a scoping symbol or what...

Compare:
/qlib/math/Vector.h:106: error: 'qMath' has not been declared
/qlib/Str.h:330: error: 'sprintf_s' was not declared in this scope

Second error is an easy fix, added just for reference here.

Edit: I forgot to mention that I've also tried to include math.h directly from vector.h which changes nothing from the original compilation routine. Can the qMath class be being ignored by gcc without generating warnings or errors or something of that nature?
Nov 11 '08 #9

Banfa
Expert Mod 5K+
P: 8,916
No GCC would not be ignoring qMath for no reason without a diagnostic.

Can you post the preprocessor commands from each file please (2 headers and a cpp I presume).
Nov 11 '08 #10

P: 12
No .cpp file since it tries to compile object code for the precompiled header first. I hope you're prepared for quite a bit of code. I've included everything up to pertinent parts except for other headers.

Expand|Select|Wrap|Line Numbers
  1. //    qlib/precompiled.h
  2. //
  3.  
  4. #ifndef __PRECOMPILED_H__
  5. #define __PRECOMPILED_H__
  6.  
  7. //---------------------------------------------------------
  8.  
  9. #if !defined( _DEBUG ) && !defined( NDEBUG )
  10.     // dont generate asserts
  11.     #define NDEBUG
  12. #endif
  13.  
  14. #if defined( _WIN32 )
  15.  
  16. #define    WIN32_LEAN_AND_MEAN
  17.  
  18. #include <winsock2.h>
  19. #include <mmsystem.h>
  20.  
  21. #define    DIRECTINPUT_VERSION    0x0700
  22. #define    DIRECTSOUND_VERSION    0x0800
  23.  
  24. #pragma warning (disable : 4244)        // conversion to smaller type, possible loss of data
  25.  
  26. #include <malloc.h>
  27. #include <windows.h>
  28. #undef FindText
  29.  
  30. #endif //_WIN32
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <stdarg.h>
  35. #include <string.h>
  36. #include <assert.h>
  37. #include <math.h>
  38.  
  39. #include "../sys/Public.h"
  40.  
  41. //---------------------------------------------------------
  42.  
  43. // qLib
  44. #include "../qlib/Lib.h"
  45.  
...omitting rest of file.

Expand|Select|Wrap|Line Numbers
  1. //    Lib.h
  2. //
  3.  
  4. #ifndef __LIB_H__
  5. #define __LIB_H__
  6.  
  7. /*
  8. ===============================================================================
  9.  
  10.     Basic library interface
  11.  
  12. ===============================================================================
  13. */
  14.  
  15. class qLib
  16. {
  17. public:
  18.     static class qSys *            sys;
  19.     static class qCommon *        common;
  20.     static class qCVarSystem *    cvarSystem;
  21.     static class qFileSystem *    fileSystem;
  22.  
  23.     static void                    Init( void );
  24.     static void                    Shutdown( void );
  25. };
  26.  
  27. /*
  28. ===============================================================================
  29.  
  30.     Types used throughout
  31.  
  32. ===============================================================================
  33. */
  34.  
  35. typedef unsigned char    byte;
  36. typedef unsigned short    word;
  37. typedef unsigned long    dword;
  38.  
  39. typedef int                qHandle_t;
  40.  
  41. #define    INVALID_HANDLE    ((qHandle_t)-1)
  42.  
  43. #ifndef NULL
  44. #define    NULL    ((void *)0)
  45. #endif
  46.  
  47. #ifndef BIT
  48. #define BIT(n)    ( 1 << ( n ) )
  49. #endif
  50.  
  51. #define    MAX_STRING_CHARS    1024
  52.  
  53. class qException {
  54. public:
  55.     char    error[MAX_STRING_CHARS];
  56.  
  57.     qException( const char *text = "" ) { strcpy( error, text ); }
  58. };
  59.  
  60. /*
  61. ===============================================================================
  62.  
  63.     qLib headers
  64.  
  65. ===============================================================================
  66. */
  67.  
  68. // memory allocation
  69. #include "Heap.h"
  70. #include "Swap.h"
  71. #include "containers/List.h"
  72.  
  73. // math
  74. #include "math/SIMD.h"
  75. #include "math/Math.h"
  76. #include "math/Random.h"
  77. #include "math/Vector.h"
  78. #include "math/Matrix.h"
  79. #include "math/Angles.h"
  80. #include "math/Quat.h"
  81. #include "math/Rotation.h"
  82. #include "math/Plane.h"
  83. #include "math/Pluecker.h"
  84. #include "math/Integrator.h"
  85.  
...omitting rest of file.

Expand|Select|Wrap|Line Numbers
  1. //    Math.h
  2. //
  3.  
  4. #ifndef __MATH_H__
  5. #define __MATH_H__
  6.  
  7. /*
  8. ===============================================================================
  9.  
  10.     Math
  11.  
  12. ===============================================================================
  13. */
  14.  
  15. #define    DEG2RAD(a)                ( (a) * qMath::M_DEG2RAD )
  16. #define    RAD2DEG(a)                ( (a) * qMath::M_RAD2DEG )
  17.  
  18. #define    SEC2MS(t)                ( qMath::FtoiFast( (t) * qMath::M_SEC2MS ) )
  19. #define MS2SEC(t)                ( (t) * qMath::M_MS2SEC )
  20.  
  21. #define FLOATSIGNBITSET(f)        ((*(const unsigned long *)&(f)) >> 31)
  22. #define FLOATSIGNBITNOTSET(f)    ((~(*(const unsigned long *)&(f))) >> 31)
  23. #define INTSIGNBITSET(i)        (((const unsigned long)(i)) >> 31)
  24. #define INTSIGNBITNOTSET(i)        ((~((const unsigned long)(i))) >> 31)
  25.  
  26. #define FLOATSIGN(f)            ( FLOATSIGNBITSET(f) ? -1 : 1 )
  27. #define INTSIGN(i)                ( INTSIGNBITSET(i) ? -1 : 1 )
  28.  
  29. #define    FLOAT_IS_NAN(x)            (((*(const unsigned long *)&x) & 0x7f800000) == 0x7f800000)
  30. #define FLOAT_IS_INF(x)            (((*(const unsigned long *)&x) & 0x7fffffff) == 0x7f800000)
  31. #define FLOAT_IS_IND(x)            ((*(const unsigned long *)&x) == 0xffc00000)
  32.  
  33. template<class T> Q_INLINE T    Max( T x, T y ) { return ( x > y ) ? x : y; }
  34. template<class T> Q_INLINE T    Min( T x, T y ) { return ( x < y ) ? x : y; }
  35. template<class T> Q_INLINE T    Clamp( T x, T y, T z ) { return ( x < y ) ? y : ( x > z ) ? z : x; }
  36.  
  37. template<class T> Q_INLINE T    Square( T x ) { return x * x; }
  38. template<class T> Q_INLINE T    Cube( T x ) { return x * x * x; }
  39.  
  40. class qMath {
  41. public:
  42.     static float            RSqrt( float x );
  43.     static float            InvSqrt( float x );
  44.  
  45.     static float            Sqrt( float x );
  46.  
  47.     static void                SinCos( float a, float &s, float &c );
  48.  
  49.     static float            ACos( float a );
  50.  
  51.     static float            Tan( float a );
  52.     static double            Tan64( float a );
  53.  
  54.     static int                Abs( int x );
  55.     static float            Fabs( float x );
  56.  
  57.     static int                Ftoi( float f );
  58.     static int                FtoiFast( float f );
  59.     static unsigned long    Ftol( float f );
  60.     static unsigned long    FtolFast( float f );
  61.  
  62.     static int                FloatHash( const float *arr, const int count );
  63.  
  64.     static const float        PI;                //    pi
  65.     static const float        TWOPI;            //    pi * 2
  66.     static const float        HALFPI;            //    pi / 2
  67.     static const float        FOURTHPI;        //    pi / 4
  68.     static const float        M_DEG2RAD;        //    degrees to radians multiplier
  69.     static const float        M_RAD2DEG;        //    radians to degrees multiplier
  70.     static const float        M_SEC2MS;        //    seconds to milliseconds multiplier
  71.     static const float        M_MS2SEC;        //    milliseconds to seconds multiplier
  72.     static const float        INFINITY;        //    huge number which should be larger than any valid number
  73. };
  74.  
  75. Q_INLINE float qMath::RSqrt( float x ) {
  76.     int    i;
  77.     float y, r;
  78.  
  79.     y = x * 0.5f;
  80.     i = *reinterpret_cast< int *>( &x );
  81.     i = 0x5f3759df - ( i >> 1 );
  82.     r = *reinterpret_cast< float *>( &i );
  83.     r = r * ( 1.5f - r * r * y );
  84.  
  85.     return r;
  86. }
  87.  
  88. Q_INLINE float qMath::InvSqrt( float x ) {
  89.     int        i;
  90.  
  91.     //    http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf suggests 0x5f375a86
  92.     double y = x * 0.5f;
  93.     i = *reinterpret_cast<int *>( &x );
  94.     i = 0x5f3759df - ( i >> 1 );                //    initial guess
  95.     double r = *reinterpret_cast<float *>( &i );
  96.     r = r * ( 1.5f - r * r * y );                //    newtonian step
  97.     r = r * ( 1.5f - r * r * y );
  98.  
  99.     return (float )r;
  100. }
  101.  
  102. Q_INLINE float qMath::Sqrt( float x ) {
  103.     return x * InvSqrt( x );
  104. }
  105.  
  106. Q_INLINE void qMath::SinCos( float a, float &s, float &c ) {
  107.     s = sinf( a );
  108.     c = cosf( a );
  109. }
  110.  
  111. Q_INLINE float qMath::Tan( float a ) {
  112.     return tanf( a );
  113. }
  114.  
  115. Q_INLINE double qMath::Tan64( float a ) {
  116.     return tan( a );
  117. }
  118.  
  119. Q_INLINE float qMath::ACos( float a ) {
  120.     if ( a <= -1.0f ) {
  121.         return PI;
  122.     }
  123.     if ( a >= 1.0f ) {
  124.         return 0.0f;
  125.     }
  126.     return acosf( a );
  127. }
  128.  
  129. Q_INLINE int qMath::Abs( int x ) {
  130.     int    y = x >> 31;
  131.     return ( x ^ y ) - y;
  132. }
  133.  
  134. Q_INLINE float qMath::Fabs( float x ) {
  135.     int    i = *reinterpret_cast<int *>( &x );
  136.     i &= 0x7fffffff;
  137.     return *reinterpret_cast<float *>( &i );
  138. }
  139.  
  140. Q_INLINE int qMath::Ftoi( float f ) {
  141.     return (int )( f );
  142. }
  143.  
  144. Q_INLINE int qMath::FtoiFast( float f ) {
  145. #ifdef _WIN32
  146.     int    i;
  147.     __asm fld    f
  148.     __asm fistp    i
  149.     return i;
  150. #else
  151.     return (int )f;
  152. #endif
  153. }
  154.  
  155. Q_INLINE unsigned long qMath::Ftol( float f ) {
  156.     return (unsigned long )( f );
  157. }
  158.  
  159. Q_INLINE unsigned long qMath::FtolFast( float f ) {
  160. #ifdef _WIN32
  161.     int    i;
  162.     __asm fld    f
  163.     __asm fistp    i
  164.     return i;
  165. #else
  166.     return (unsigned long )( f );
  167. #endif
  168. }
  169.  
  170. Q_INLINE int qMath::FloatHash( const float *arr, const int count ) {
  171.     int i, hash = 0;
  172.     const int *ptr;
  173.  
  174.     ptr = reinterpret_cast<const int *>( arr );
  175.     for ( i=0 ; i<count ; i++ ) {
  176.         hash ^= ptr[ i ];
  177.     }
  178.     return hash;
  179. }
  180.  
  181. #endif //__MATH_H__
  182.  
Expand|Select|Wrap|Line Numbers
  1. //    Vector.h
  2. //
  3.  
  4. #ifndef __MATH_VECTOR_H__
  5. #define __MATH_VECTOR_H__
  6.  
  7. /*
  8. ===============================================================================
  9.  
  10.     Vector classes
  11.  
  12. ===============================================================================
  13. */
  14.  
  15. #define    VECTOR_EPSILON    0.001f
  16.  
  17. class qAngles;
  18. class qMat3;
  19.  
  20. /*
  21. ===================
  22. qVec2
  23. ===================
  24. */
  25.  
  26. class qVec2
  27. {
  28. public:
  29.     float            x;
  30.     float            y;
  31.  
  32.                     qVec2( void );
  33.                     qVec2( const float X, const float Y );
  34.  
  35.     void            Set( const float X, const float Y );
  36.     void            Clear( void );
  37.     void            Zero( void );
  38.  
  39.     float            operator[]( int index ) const;
  40.     float &            operator[]( int index );
  41.     qVec2            operator-() const;
  42.     float            operator*( const qVec2 &a ) const;    // dot product
  43.     float            operator^( const qVec2 &a ) const;    // cross product
  44.     qVec2            operator*( const float a ) const;
  45.     qVec2            operator/( const float a ) const;
  46.     qVec2            operator+( const qVec2 &a ) const;
  47.     qVec2            operator-( const qVec2 &a ) const;
  48.     qVec2 &            operator+=( const qVec2 &a );
  49.     qVec2 &            operator-=( const qVec2 &a );
  50.     qVec2 &            operator*=( const float a );
  51.     qVec2 &            operator/=( const float a );
  52.  
  53.     friend qVec2    operator*( const float a, const qVec2 b );
  54.  
  55.     bool            Compare( const qVec2 &a ) const;
  56.     bool            Compare( const qVec2 &a, const float epsilon ) const;
  57.     bool            operator==( const qVec2 &a ) const;
  58.     bool            operator!=( const qVec2 &a ) const;
  59.  
  60.     float            Dot( const qVec2 &a ) const;
  61.     float            Cross( const qVec2 &a ) const;    // bi-linear anti-commutative
  62.     qVec2            Cross( void ) const;            // orthogonal vector
  63.     float            Length( void ) const;
  64.     float            LengthSq( void ) const;
  65.     float            Normalize( void );
  66.  
  67.     const float *    ToFloatPtr( void ) const;
  68.     float *            ToFloatPtr( void );
  69.     const char *    ToString( int precision = 2 ) const;
  70.  
  71.     void            Lerp( const qVec2 &v1, const qVec2 &v2, const float l );
  72. };
  73.  
  74. extern qVec2 vec2_origin;
  75. #define vec2_zero vec2_origin
  76.  
  77. Q_INLINE qVec2::qVec2( void ) {
  78. }
  79.  
  80. Q_INLINE qVec2::qVec2( const float X, const float Y ) {
  81.     x = X;
  82.     y = Y;
  83. }
  84.  
  85. Q_INLINE void qVec2::Set( const float X, const float Y ) {
  86.     x = X;
  87.     y = Y;
  88. }
  89.  
  90. Q_INLINE void qVec2::Clear( void ) {
  91.     x = y = 0.0f;
  92. }
  93.  
  94. Q_INLINE void qVec2::Zero( void ) {
  95.     x = y = 0.0f;
  96. }
  97.  
  98. Q_INLINE bool qVec2::Compare( const qVec2 &a ) const {
  99.     return ( ( x == a.x ) && ( y == a.y ) );
  100. }
  101.  
  102. Q_INLINE bool qVec2::Compare( const qVec2 &a, const float epsilon ) const {
  103.     if ( qMath::Fabs( x - a.x ) > epsilon )
  104.         return false;
  105.  
  106.     if ( qMath::Fabs( y - a.y ) > epsilon )
  107.         return false;
  108.     return true;
  109. }
  110.  
...omitting rest of file.
This first reference and all subsequent references to qMath generate the errors.
Nov 11 '08 #11

weaknessforcats
Expert Mod 5K+
P: 9,197
I do not see the qMatch class or the inline function qMatch::Fabs in your vector.h.

Are you sure this class has been included before vector.h in your source file?
Nov 11 '08 #12

P: 12
All source files include the precompiled header 'qlib/precompiled.h' which includes the header files in the order shown.

qMath::Fabs is declared and defined in qlib/math/Math.h which is included by qlib/Lib.h two lines before qlib/math/Vector.h which, as I understand it, means that qMath will always be declared when parsing Vector.h.
Nov 11 '08 #13

Expert 100+
P: 2,415
I'm just an old C programmer, so this comment may not make sense in the brave new C++ world ...

Math.h doesn't include any files ... then how does it expect to reliably get a definition for Q_INLINE? Presumably that is supposed to be a macro that expands to "inline". Would a problem with that macro cause any of the symptoms you're seeing?
Nov 11 '08 #14

P: 12
I'm just an old C programmer, so this comment may not make sense in the brave new C++ world ...

Math.h doesn't include any files ... then how does it expect to reliably get a definition for Q_INLINE? Presumably that is supposed to be a macro that expands to "inline". Would a problem with that macro cause any of the symptoms you're seeing?
Math.h is always included in sequence with other header files by the precompiled header. Q_INLINE is defined in ../sys/Public.h which is the first user file included by the precompiled header..

Your question definitely makes sense and is valid in C++, it's just the precompiled header strategy used in project that's throwing you off.
Nov 11 '08 #15

P: 12
It gets better...

Code compiles without any problems in cygwin using gcc 3.4.4
Nov 12 '08 #16

P: 12
Problem solved, turns out to be very silly. The include guard in qlib/math/Math.h ( __MATH_H__ ) was being defined in one of the system libraries which caused the compiler to essentially ignore the entire file. Changing the guard define solved everything.
Nov 12 '08 #17

Banfa
Expert Mod 5K+
P: 8,916
Good catch I thought about and should have mentioned the standard header math.h earlier, sorry.
Nov 12 '08 #18

Post your reply

Sign in to post your reply or Sign up for a free account.