actually, in theory, I think that sizeof(Matrix4x4) should be strictly greater then 16*sizeof(float) as far as standard C++ is concerned, and so that GCC is correct and that VC++ is wrong.

indeed, according to

Quote Originally Posted by C++2003 - 10.5
A base class subobject might have a layout (3.7) different from the layout of a most derived object of the same type. A base class subobject might have a polymorphic behavior (12.7) different from the polymorphic behavior of a most derived object of the same type. A base class subobject may be of zero size (clause 9); however, two subobjects that have the same class type and that belong to the same most derived object must not be allocated at the same address (5.10).
the rationale being that every distinct object of the same type should have a distinct address. So, the code

Code:
struct Base
{
    // helper functions here
};

struct Vector4 : public Base
{
    float x, y, z, w;
};

struct Matrix4x4 : public Base
{
    Vector4 rows[4];
};

int main()
{
	Matrix4x4 	m;
	Base* 		pb1 = &m;
	Base* 		pb2 = m.rows;

	_ASSERT( pb1 != pb2 );
}
should never fail on a conforming compiler ( and fails on VC++2008 ); that said, a quick google search on the subject shows that compilers generally behave weirdly on this regard and, to be honest, that the standard is not very clear on this point ( for example, what does it mean "allocating an object of zero size" ? I mean, is the compiler allowed, say, to set the address of the second Base subobject to <any> address included in the memory region spanned by subobjects of different type ? )