Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Errors when trying to declare a varibale as extern[SOLVED]
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Portage & Programming
View previous topic :: View next topic  
Author Message
tenspd137
Guru
Guru


Joined: 22 Aug 2006
Posts: 391

PostPosted: Tue Nov 20, 2012 12:46 am    Post subject: Errors when trying to declare a varibale as extern[SOLVED] Reply with quote

Hi all,

I am having trouble compiling anything that uses a header file where I am declaring some variables extern. It looks like this (simplified it)

Code:

#ifndef _HEADER_H_
#define _HEADER_H_

class Vec3
{
        private:
               ........  private stuff ............
        public:
               .......... public stuff .............
};

extern Vec3 g_Up;

....... more stuff .......


Whenever I use this include file, it complains about a storage class specified for g_Up and that g_Up has an incomplete type.

Now, if I replace my class with say glm::vec3 with a typedef:
Code:

#ifndef _HEADER_H_
#define _HEADER_H_

#include <glm/glm.h>

typedef glm::vec3 Vec3;

extern Vec3 g_Up;

....... more stuff .......


it has no problem with that. I know I am missing something - could someone tell me the right way to do this if I am writing my own class?

Thanks!


Last edited by tenspd137 on Tue Nov 20, 2012 6:32 am; edited 1 time in total
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21633

PostPosted: Tue Nov 20, 2012 2:08 am    Post subject: Reply with quote

You have simplified out one or more critical lines. The following example, inspired by what you did post, works for me.
Code:
class X
{
private:
public:
};
extern X x;
Back to top
View user's profile Send private message
tenspd137
Guru
Guru


Joined: 22 Aug 2006
Posts: 391

PostPosted: Tue Nov 20, 2012 6:19 am    Post subject: Reply with quote

Yeah - I was hoping it was just something I missed. I was on my way out the door when I wrote that. Here is the actual .h file I am using:

Geometry.h
Code:

#ifndef _GEOMETRY_H_
#define _GEOMETRY_H_

const float  GCC_PI = 3.14159265358979f;
const float  GCC_2PI = 2 * GCC_PI;

#ifndef _WIN32_
#include <glm/glm.hpp>
#include "glm/gtc/quaternion.hpp"
#endif

////////////////////////////////////////////////////
//
// Utility classes for vectors and matrices
//
////////////////////////////////////////////////////
#ifdef _WIN32_
typedef D3DXVECTOR2 Vec2;
#else
typedef glm::vec2 Vec2;
#endif
////////////////////////////////////////////////////
//
// Vec3 Description
//
//
////////////////////////////////////////////////////
#ifdef _WIN32_
class Vec3 : public D3DXVECTOR3
{
  public:
    inline float Length() { return D3DXVec3Length(this); }
    inline Vec3 *Normalize() { return static_cast<Vec3 *>(D3DXVec3Normalize(this, this)); }
    inline float Dot(const Vec3 &b) { return D3DXVec3Dot(this, &b); }
    inline Vec3 Cross(const Vec3 &b) const;

    Vec3(D3DXVECTOR3 &v3) { x = v3.x; y = v3.y; z = v3.z; }
    Vec3() : D3DXVECTOR3() { x = 0; y = 0; z = 0; }
    Vec3(const float _x, const float _y, const float _z) { x=_x; y=_y; z=_z; }
    Vec3(const double _x, const double _y, const double _z) { x = (float)_x; y = (float)_y; z = (float)_z; }
    inline Vec3(const class Vec4 &v4);
};

inline Vec3 Vec3::Cross(const Vec3 &b) const
{
    Vec3 out;
    D3DXVec3Cross(&out, this, &b);
    return out;
}
#else
class Vec3
{
   private:
      glm::vec3 m_vec;
   public:
      inline float Length() { return glm::length(m_vec); }
      inline Vec3* Normalize() { m_vec = glm::normalize(m_vec); return this; }
      inline float Dot(const Vec3 &b) { return glm::dot(m_vec, b.m_vec};
      inline Vec3 Cross(const Vec3 &b) const
      {
         return Vec3(glm::cross(m_vec, b.m_vec));
      }
      Vec3(glm::vec3 &v3) { m_vec.x = v3.x; m_vec.y = v3.y; m_vec.z = v3.z; }
      Vec3() { m_vec.x = 0; m_vec.y = 0; m_vec.z = 0 };
      Vec3(const float _x, const float _y, const float _z) { m_vec.x = x; m_vec.y = y; m_vec.z = z; }
      Vec3(const double _x, const double _y, const double _z) { m_vec.x = (float)_x; m_vec.y = (float)_y; m_vec.z = (float)_z; }
       inline Vec3(const class Vec4 &v4);
};
   
#endif



////////////////////////////////////////////////////
//
// Vec4 Description
//
//
////////////////////////////////////////////////////

#ifdef _WIN32_
class Vec4 : public D3DXVECTOR4
{
  public:
    inline float Length() { return D3DXVec4Length(this); }
    inline Vec4 *Normalize() { return static_cast<Vec4 *>(D3DXVec4Normalize(this, this)); }
    // If you want the cross product, use Vec3::Cross
    inline float Dot(const Vec4 &b) { return D3DXVec4Dot(this, &b); }

    Vec4(D3DXVECTOR4 &v4)  { x = v4.x; y = v4.y; z = v4.z; w = v4.w; }
    Vec4() : D3DXVECTOR4() { }
    Vec4(const float _x, const float _y, const float _z, const float _w) { x=_x; y=_y; z=_z; w=_w; }
    Vec4(const Vec3 &v3) { x = v3.x; y = v3.y; z = v3.z; w = 1.0f; }

};

inline Vec3::Vec3(const Vec4 &v4) { x = v4.x; y = v4.y; z = v4.z; }
#else
class Vec4
{
   private:
      glm::vec4 m_vec;
      friend class Vec3;
   public:
      inline float Length() { return glm::length(m_vec); }
      inline Vec4* Normalize() { m_vec = glm::normalize(m_vec); return this; }
      inline float Dot(const Vec4 &v4) { return glm::dot(m_vec, b.m_vec};
      
      Vec4(glm::vec4 &v4) { m_vec.x = v4.x; m_vec.y = v4.y; m_vec.z = v4.z; m_vec.w = v4.w; }
      Vec4() { m_vec.x = 0; m_vec.y = 0; m_vec.z = 0; m_vec.w = 0; }
      Vec4(const float _x, const float _y, const float _z, const float _w) { m_vec.x=_x; m_vec.y=_y; m_vec.z=_z; m_vec.w=_w; }

};

inline Vec3::Vec3(const Vec4 &v4) { m_vec.x = v4.m_vec.x; m_vec.y = v4.m_vec.y; m_vec.z = v4.m_vec.z; }
#endif

extern Vec3 g_Up;
extern Vec3 g_Right;
extern Vec3 g_Forward;

extern Vec4 g_Up4;
extern Vec4 g_Right4;
extern Vec4 g_Forward4;
#endif


I made one change - I tried to make sure Vec3 and Vec4 were both defined using inlines. But that just gives me an error about incomplete classes. I am compiling this with GCC 4.7.2:
Code:
 
g++ -c -std=c++11 Geometry.h


and the output I get is:

Geometry.h:1:9: warning: #pragma once in main file [enabled by default]
Geometry.h:165:33: error: invalid use of incomplete type ‘class Vec3’
Geometry.h:101:7: error: forward declaration of ‘class Vec3’
Geometry.h:168:13: error: storage class specified for ‘g_Up’
Geometry.h:168:13: error: field ‘g_Up’ has incomplete type
Geometry.h:169:13: error: storage class specified for ‘g_Right’
Geometry.h:169:13: error: field ‘g_Right’ has incomplete type
Geometry.h:170:13: error: storage class specified for ‘g_Forward’
Geometry.h:170:13: error: field ‘g_Forward’ has incomplete type
Geometry.h:172:13: error: storage class specified for ‘g_Up4’
Geometry.h:172:13: error: field ‘g_Up4’ has incomplete type
Geometry.h:173:13: error: storage class specified for ‘g_Right4’
Geometry.h:173:13: error: field ‘g_Right4’ has incomplete type
Geometry.h:174:13: error: storage class specified for ‘g_Forward4’
Geometry.h:174:13: error: field ‘g_Forward4’ has incomplete type

What I don't understand is that I thought that I basically defined Vec3 and Vec4 using glm.

Basically, I was trying to take sample code from a programming book that was Windows based and port it to linux. To do this, I was compiling individual pieces using the line above (replacing the files of course) but this header is giving me problems.

What I can tell is that it doesn't like the following lines:
inline Vec3(const class Vec4 &v4); (in the class declaration)
and
inline Vec3::Vec3(const Vec4 &v4) { m_vec.x = v4.m_vec.x; m_vec.y = v4.m_vec.y; m_vec.z = v4.m_vec.z; }
after the Vec4 declaration - which I don't get. Then - I have the same problem earlier with extern not working.

Sorry for the really vague post earlier.

Thanks!

##Edit: Figured out the inline part - I had a misplaced ; in the declaration. I fixed it above in the listing.
Back to top
View user's profile Send private message
tenspd137
Guru
Guru


Joined: 22 Aug 2006
Posts: 391

PostPosted: Tue Nov 20, 2012 6:34 am    Post subject: Reply with quote

Okay - so I feel incredibly lame. There were more syntax error / typos than I thought. After several more recompiles - I figured it out.

Code:

#ifndef _GEOMETRY_H_
#define _GEOMETRY_H_

const float  GCC_PI = 3.14159265358979f;
const float  GCC_2PI = 2 * GCC_PI;

#ifndef _WIN32_
#include <glm/glm.hpp>
#include "glm/gtc/quaternion.hpp"
#endif

////////////////////////////////////////////////////
//
// Utility classes for vectors and matrices
//
////////////////////////////////////////////////////
#ifdef _WIN32_
typedef D3DXVECTOR2 Vec2;
#else
typedef glm::vec2 Vec2;
#endif
////////////////////////////////////////////////////
//
// Vec3 Description
//
//
////////////////////////////////////////////////////
#ifdef _WIN32_
class Vec3 : public D3DXVECTOR3
{
  public:
    inline float Length() { return D3DXVec3Length(this); }
    inline Vec3 *Normalize() { return static_cast<Vec3 *>(D3DXVec3Normalize(this, this)); }
    inline float Dot(const Vec3 &b) { return D3DXVec3Dot(this, &b); }
    inline Vec3 Cross(const Vec3 &b) const;

    Vec3(D3DXVECTOR3 &v3) { x = v3.x; y = v3.y; z = v3.z; }
    Vec3() : D3DXVECTOR3() { x = 0; y = 0; z = 0; }
    Vec3(const float _x, const float _y, const float _z) { x=_x; y=_y; z=_z; }
    Vec3(const double _x, const double _y, const double _z) { x = (float)_x; y = (float)_y; z = (float)_z; }
    inline Vec3(const class Vec4 &v4);
};

inline Vec3 Vec3::Cross(const Vec3 &b) const
{
    Vec3 out;
    D3DXVec3Cross(&out, this, &b);
    return out;
}
#else
class Vec3
{
   private:
      glm::vec3 m_vec;
   public:
      inline float Length() { return glm::length(m_vec); }
      inline Vec3* Normalize() { m_vec = glm::normalize(m_vec); return this; }
      inline float Dot(const Vec3 &b) { return glm::dot(m_vec, b.m_vec);}
      Vec3() { m_vec.x = 0; m_vec.y = 0; m_vec.z = 0; }
      inline Vec3 Cross(const Vec3 &b) const
      {
          glm::vec3 v = glm::cross(m_vec,b.m_vec);
         return Vec3(v);
      }
      Vec3(glm::vec3 &v3) { m_vec.x = v3.x; m_vec.y = v3.y; m_vec.z = v3.z; }
     
      Vec3(const float _x, const float _y, const float _z) { m_vec.x = _x; m_vec.y = _y; m_vec.z = _z; }
      Vec3(const double _x, const double _y, const double _z) { m_vec.x = (float)_x; m_vec.y = (float)_y; m_vec.z = (float)_z; }
      inline Vec3(const class Vec4 &v4);
};
   
#endif



////////////////////////////////////////////////////
//
// Vec4 Description
//
//
////////////////////////////////////////////////////

#ifdef _WIN32_
class Vec4 : public D3DXVECTOR4
{
  public:
    inline float Length() { return D3DXVec4Length(this); }
    inline Vec4 *Normalize() { return static_cast<Vec4 *>(D3DXVec4Normalize(this, this)); }
    // If you want the cross product, use Vec3::Cross
    inline float Dot(const Vec4 &b) { return D3DXVec4Dot(this, &b); }

    Vec4(D3DXVECTOR4 &v4)  { x = v4.x; y = v4.y; z = v4.z; w = v4.w; }
    Vec4() : D3DXVECTOR4() { }
    Vec4(const float _x, const float _y, const float _z, const float _w) { x=_x; y=_y; z=_z; w=_w; }
    Vec4(const Vec3 &v3) { x = v3.x; y = v3.y; z = v3.z; w = 1.0f; }

};

inline Vec3::Vec3(const Vec4 &v4) { x = v4.x; y = v4.y; z = v4.z; }
#else
class Vec4
{
   private:
      glm::vec4 m_vec;
      friend class Vec3;
   public:
      inline float Length() { return glm::length(m_vec); }
      inline Vec4* Normalize() { m_vec = glm::normalize(m_vec); return this; }
      inline float Dot(const Vec4 &v4) { return glm::dot(m_vec, v4.m_vec);}
     
      Vec4(glm::vec4 &v4) { m_vec.x = v4.x; m_vec.y = v4.y; m_vec.z = v4.z; m_vec.w = v4.w; }
      Vec4() { m_vec.x = 0; m_vec.y = 0; m_vec.z = 0; m_vec.w = 0; }
      Vec4(const float _x, const float _y, const float _z, const float _w) { m_vec.x=_x; m_vec.y=_y; m_vec.z=_z; m_vec.w=_w; }

};

inline Vec3::Vec3(const Vec4 &v4) { m_vec.x = v4.m_vec.x; m_vec.y = v4.m_vec.y; m_vec.z = v4.m_vec.z; }
#endif

extern Vec3 g_Up;
extern Vec3 g_Right;
extern Vec3 g_Forward;

extern Vec4 g_Up4;
extern Vec4 g_Right4;
extern Vec4 g_Forward4;
#endif

Compiles cleanly.

Sorry everyone - thanks Hu for looking at it.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Portage & Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum