Sign in to follow this  
Floating

sizeof(Class)

Recommended Posts

Hello, For following Class, I was very surprised to get a sizeof(C4Vector) of 20. I was expecting 16. Where are the additional 4 bytes allocated?? I can only see the float data[4]

class C4Vector  
{
public:

//------------------- Construction/destruction ---------------
	C4Vector();
	C4Vector(float v0,float v1,float v2,float v3);
	C4Vector(float v[4]);
	C4Vector(const C3Vector& v);
	C4Vector(const C4Vector& q);
	C4Vector(float a,float b,float g);
	C4Vector(float angle,const C3Vector& axis);
	C4Vector(const C3Vector& startV,const C3Vector& endV);
	virtual ~C4Vector();
//------------------------------------------------------------

//------------------- Various functions ----------------------
//	void serialize(CSer& ar);
	void clear();
	void setIdentity();
	void setEulerAngles(const C3Vector& v);
	void setEulerAngles(float a,float b,float g);
	void setAngleAndAxis(float angle,const C3Vector& axis);
	void setVectorMapping(const C3Vector& startV,const C3Vector& endV);
	void buildInterpolation(const C4Vector& fromThis,const C4Vector& toThat,float t);
	C4Vector getAngleAndAxis() const;
	C3Vector getEulerAngles() const;
	C4Vector getInverse() const;
	void inverse();
	C3X3Matrix getMatrix() const;
	void normalize();
	C3Vector getAxis(int index) const;
//------------------------------------------------------------

//------------------- Operator overloading -------------------
	C4Vector operator/ (float d) const;
	C4Vector operator* (float d) const;
	C4Vector operator+ (const C4Vector& v) const;
	C4Vector operator* (const C4Vector& v) const;

	void operator/= (float d);
	void operator*= (float d);
	void operator+= (const C4Vector& v);
	void operator*= (const C4Vector& v);

	float&	operator() (unsigned i);
	const float& operator() (unsigned i) const;
	C4Vector& operator= (const C4Vector& v);
	C3Vector operator* (const C3Vector& v) const; // Rotation of a vector
//------------------------------------------------------------

//------------------- Private variables ----------------------
private:
	float data[4];
//------------------------------------------------------------
};

//------------------- Inlined functions ----------------------

inline float& C4Vector::operator() (unsigned i)
{
	SIM_ASSERT(i<4);
	return(data[i]);
}

inline const float& C4Vector::operator() (unsigned i) const
{
	SIM_ASSERT(i<4);
	return(data[i]);
}


Share this post


Link to post
Share on other sites
Because of the vtable pointer, which is commonly at the start of the object but this is not guaranteed.

You get a vtable pointer if you have any virtual functions, such as your virtual destructor. For the most part, you only need a virtual destructor if you're ever going to delete an instance of a derived class via a pointer to the base. Since, generally, mathematical vector classes such as yours are not part of an inheritance hierarchy, you probably don't need the virtual specifier on the destructor.

Share this post


Link to post
Share on other sites
This is why for very lightweight objects such as a vector or a matrix, it isn't necessarily wise to have virtual functions. Not to mention that it messes up packing if you try to feed data to the graphics card.

Share this post


Link to post
Share on other sites
There is no guarantee as to where the vtable goes, which can yield some interesting results if you don't pay attention to the "never cast to void *" rule.

Assume you have a baseclass with no virtual functions, and a derived class with virtuals.

In MSVC the vtable is at offset 0. In gcc the vtable comes after the baseclass data. In MSVC if you cast your derived class pointer to the base class, it automatically adds 4 to the pointer, as the base class has no vtable. If you cast down to the dervied class, it automatically subtracts 4. This is all fine. Now imagine you cast a base class pointer (obj+4) to void * (remains obj+4), then to the derived class (remains obj+4). The compiler doesn't know that the void * used to be a base *, and has no reason to change the pointer. You can no longer use your class. MSVC tries to fix these problems if you do the casts in one function, but if you're passing pointers around, you can run into this. You should avoid void * at all costs.

Share this post


Link to post
Share on other sites
Quote:
Original post by Namethatnobodyelsetook
There is no guarantee as to where the vtable goes ... In MSVC the vtable is at offset 0.


That's not guaranteed either. Multiple inheritance will give you multiple vptrs for example. You also derive a class with a virtual function from one without one and the vptr will end up in the middle.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this