In file included from src/Vector.cpp:17:
include/ngl/Vector.h(476) : error: 'm_x' is a protected member of 'ngl::Vector'
return Vector(_k*_v.m_x, _k*_v.m_y, _k*_v.m_z,_v.m_w);
^
include/ngl/Vector.h(423) : note: declared protected here
Real m_x;
^
This is fair enough however this compiled fine with g++, after turning on the pedantic flag in g++ I got the following error
In file included from src/Vector.cpp:17:
include/ngl/Vector.h:437: error: ISO C++ prohibits anonymous structs
Now this is where the plot thickens and I learnt something new.
So clang++ says I have a visibility problem, whereas g++ running normally says this is fine, and g++ in full pedantic mode say no way, who is correct and what is going on?
A Simple Test Class
To test the problems I was encountering I decided to write a simple class as shown below
class Vector { public : Vector( const Vector& _v ) : m_x(_v.m_x), m_y(_v.m_y), m_z(_v.m_z), m_w(_v.m_w){;} Vector( const float& _x=0.0, const float& _y=0.0, const float& _z=0.0, const float& _w=1.0f ): m_x(_x), m_y(_y), m_z(_z), m_w(_w){;} private : union { struct { float m_x; float m_y; float m_z; float m_w; }; float m_openGL[4]; }; };So here we have a simple union of 4 floats and an array of 4 floats which if we look at the memory layout would look like this
I then wrote a simple test program which looked like this
int main() { Vector v(1.0,2.0,3.0,1.0); v.m_x=2.0; std::cout<< v.m_x<<"\n"; }You will notice in the above program, that I access the member m_x directly. However in the class this is declared in the private section. How does this work?
Well i'm not really sure, according to clang++ "anonymous structs are a GNU extension" so are allowed, however this doesn't account for the breaking of encapsulation.
After further tests I moved the union into the protected area and still it works and I can access the member directly. So it would appear that anonymous struct / unions are always public.
Testing this with Visual Studio 2005 I get the same results, however with the new version of clang++ that ships with Xcode 4 (Apple clang version 2.0 (tags/Apple/clang-137) (based on LLVM 2.9svn)) I get the following
clang++ -pedantic -fdiagnostics-fixit-info VecTest.cpp -o Test
VecTest.cpp:30:5: warning: anonymous structs are a GNU extension [-Wgnu]
struct
^
VecTest.cpp:46:4: error: 'm_x' is a protected member of 'Vector'
v.m_x=2.0;
^
VecTest.cpp:32:13: note: declared protected here
float m_x;
^
VecTest.cpp:47:15: error: 'm_x' is a protected member of 'Vector'
std::cout<<v.m_x<<"\n";
^
VecTest.cpp:32:13: note: declared protected here
float m_x;
^
1 warning and 2 errors generated.
So it seems clang++ deals with the visibility / scope correctly unlike the other two compilers, for now I think I'm going to move the structs in my library to public anyway as this will give me more speed / access for the basic math classes.
No comments:
Post a Comment