Skip to main content
GameDev.net gamedev.net
🔒 Locked

missing type specifier, why?

Started by clashie Jul 2, 2010 at 2:21 AM 8 replies 3.2k views
Original Post
clashie
clashie
#pragma once#include "math.h"#include "vector.h"namespace bnr	{namespace math	{//////////////////////////////////////////////////////////////////////////	struct Matrix	{		void zero		();		void copy		(const Matrix& m);		void identity	();		void perspective(f32 fovy, f32 aspect, f32 zn, f32 zf);		void add		(const Matrix& m);		void subtract	(const Matrix& m);		void multiply	(const Matrix& m);		void divide		(const Matrix& m);		void scale		(const Vector& v);		void scale		(f32 x, f32 y, f32 z);		void translate	(const Vector& v);		void translate	(f32 x, f32 y, f32 z);		void rotate		(f32 x, f32 y, f32 z, f32 a);		void rotateX	(f32 a);		void rotateY	(f32 a);		void rotateZ	(f32 a);		__declspec(align(16)) union		{			struct			{				f32	_11, _12, _13, _14,					_21, _22, _23, _24,					_31, _32, _33, _34,					_41, _42, _43, _44;			};			f32		m[4][4];			__m128	m128[4];		};	};	//////////////////////////////////////////////////////////////////////////	inline void Matrix::zero()						{	memset(this->m, 0, 64);		}	inline void Matrix::copy(const Matrix& m)		{	memcpy(this->m, m.m, 64);	}... hundreds of lines of other functions...}}



#pragma once#include "math.h"#include "matrix.h"namespace bnr	{namespace math	{//////////////////////////////////////////////////////////////////////////	struct Vector	{		Vector()								: x(0.0f), y(0.0f), z(0.0f), w(1.0f)	{ };		Vector(f32 xp, f32 yp, f32 zp)			: x(xp), y(yp), z(zp), w(1.0f)			{ };		Vector(f32 xp, f32 yp, f32 zp, f32 wp)	: x(xp), y(yp), z(zp), w(wp)			{ };		void multiply	(const Matrix& m);		void multiply	(const Vector& v, const Matrix& m);		__declspec(align(16)) union		{			struct{ f32	x, y, z, w;	};			f32		v[4];			__m128	v128;		};	};	//////////////////////////////////////////////////////////////////////////	inline void Vector::multiply(const Matrix& m)	{	this->multiply(*this, m);		}	inline void Vector::multiply(const Vector& v, const Matrix& m)	{			__m128 vx = _mm_shuffle_ps(v.v128, v.v128, 0x00);	//broadcasts		__m128 vy = _mm_shuffle_ps(v.v128, v.v128, 0x55);		__m128 vz = _mm_shuffle_ps(v.v128, v.v128, 0xAA);		__m128 vw = _mm_shuffle_ps(v.v128, v.v128, 0xFF);			vx = _mm_mul_ps(vx, m.m128[0]);		vy = _mm_mul_ps(vy, m.m128[1]);		vz = _mm_mul_ps(vz, m.m128[2]);		vw = _mm_mul_ps(vw, m.m128[3]);		vx			= _mm_add_ps(vx, vy);		vx			= _mm_add_ps(vx, vz);		this->v128	= _mm_add_ps(vx, vw);	}//////////////////////////////////////////////////////////////////////////}}




first error points here:
void multiply	(const Matrix& m);


error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
syntax error : missing ',' before '&'

and 20 other repeating errors for every instance of Matrix within the header. I don't get it, what am I missing?
Waterwalker
Waterwalker
Vector.h includes Matrix.h which includes Vector.h which includes Matrix.h which includes Vector.h ...

You already recognized this and "solved" it by putting this pragma_once in there. But this only leads to a situation where e.g. Matrix.h includes Vector.h. Then, the compiler cannot compile Vector because this class definition uses the Matrix objects who's header he cannot include and read because you are actual inside the Matrix.h header.

Basically the rule is that not both objects can use instances of each other inside the header as references, only as pointers. To solve your problem remove all Matrix usage out of the Vector header. Then define * operators for the Vector Matrix multiplication outside of the Vector class inside the Matrix header.
------------------------------------I always enjoy being rated up by you ...
clashie
clashie
Tell me there's another work around, because I kinda like the way I have stuff laid out now. :(
Zakwayda
Zakwayda
Quote:
Basically the rule is that not both objects can use instances of each other inside the header as references, only as pointers.
Unless I'm misinterpreting you, this statement is incorrect: references can be used with types that have been forward-declared, just as pointers can.
Quote:
Original post by clashie
Tell me there's another work around, because I kinda like the way I have stuff laid out now. :(
Well, when it comes to following the rules of the language, what we 'like' doesn't really matter that much :) But, you could try forward-declaring the types and moving the function definitions to separate source files. (They could no longer be marked as inline, but as I understand it, most compilers only consider 'inline' to be a suggestion anyway.)

Anyway, IMO at least, there's really no reason that a matrix class and a vector class need to have mutual knowledge of one another. Generally, functions that operate on both types (and binary operators in general) should be implemented as non-member functions, in which case they can be moved into their own headers. This is the usual approach, and unless you're dealing with unusual constraints of some sort, it's the approach I'd recommend.
SiCrane
SiCrane
If you really want to keep the inline functions in the headers you can organize your headers like this:

matrix.h:

forward declare vector
matrix class definition
#include "vector.h"
inline function definitions

vector.h

forward declare matrix
vector class definition
#include "matrix.h"
inline function definitions
clashie
clashie
Quote:
Original post by SiCrane
If you really want to keep the inline functions in the headers you can organize your headers like this:

matrix.h:

forward declare vector
matrix class definition
#include "vector.h"
inline function definitions

vector.h

forward declare matrix
vector class definition
#include "matrix.h"
inline function definitions


This is what I ended up doing.

Is there a better way to define my inline functions?
Waterwalker
Waterwalker
Quote:
Original post by jyk
Quote:
Basically the rule is that not both objects can use instances of each other inside the header as references, only as pointers.
Unless I'm misinterpreting you, this statement is incorrect: references can be used with types that have been forward-declared, just as pointers can.

Ups ... you're right, I was not thinking too much while typing. I wanted to refer this to the non reference usages of the undefined types only.

Thanks for poiting this flaw out.
------------------------------------I always enjoy being rated up by you ...
Spell
Spell
I am currently wondering why your structs have methods O_o (why no classes?)

However have you tried something like:
struct Vector;struct Matrix{  [...]}; 


instead of including the header of Vector? I dunno if that will work but once I had an similar problem and there it solved it.
Waterwalker
Waterwalker
Quote:
Original post by Spell
I am currently wondering why your structs have methods O_o (why no classes?)

However have you tried something like:
*** Source Snippet Removed ***

instead of including the header of Vector? I dunno if that will work but once I had an similar problem and there it solved it.


That's just a forward declaration for a struct and it works, as pointed out above, for pointers and references you use inside headers. It does not work, though, for actual instances of the class because the compiler does not know how much space to allocate for such an instances (as opposed to pointers and references).

So in this case it does not help because the multiply methods return actual class instances, not only pointers or references.

However, note that the actual problem is already solved as a combination of forward declarations and an include later in the header file as you can read above.
------------------------------------I always enjoy being rated up by you ...
Zakwayda
Zakwayda
Quote:
I am currently wondering why your structs have methods O_o (why no classes?)
Why shouldn't they have methods?

In C++, structs and classes are the same (aside from default privileges), so there's nothing to stop you from using structs as the OP has done.

Granted, it's somewhat contrary to the common convention of only using structs for PODs and other simple user-defined types, but that is, after all, just a convention.
Quote:
However have you tried something like:
*** Source Snippet Removed ***

instead of including the header of Vector? I dunno if that will work but once I had an similar problem and there it solved it.
That's already been discussed (as Waterwalker pointed out).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.