I have a vector class look like this:
class Vector3
{
public:
Vector3(){m_x = m_y = m_z = 0.0f;}
Vector3(const float & i_x, const float & i_y, const float & i_z):
m_x(i_x),
m_y(i_y),
m_z(i_z)
{}
Vector3 operator+(const Vector3 & i_other);
private:
float m_x;
float m_y;
float m_z;
};
Vector3::Vector3 Vector3::operator+(const Vector3 & i_other)
{
float tx = m_x + i_other.m_x;
float ty = m_y + i_other.m_y;
float tz = m_z + i_other.m_z;
return Vector3(tx, ty, tz);
}
Obviously, the Vector3::operator+ definition synax is wrong because the return type is Vector3::Vector3, not Vector3. Vector3::Vector3 means there is a namespace Vector3, and inside the name space there is a class Vector3. But I only have a class Vector3, no namespace here.
My question is, in Ubuntu 12.04, the syntax above can not be compiled (Ubuntu’s g++ compiler is [gcc version 4.6.3]). However, in Mac, g++ can compile the code(Mac’s g++ compiler is [gcc version 4.2.1]). Also, I test this syntax in a Red Hat linux machine, it also works (g++ version is [gcc version 4.4.6])
So, is it different version of gcc have different compile principle? Or, my g++ in Ubuntu broke?
The older compiler is incorrect. Little surprise there.
It is probably parsing
Vector3::Vector3as an injected-type-name. Inside the scope ofclass Vector3 { }, the identifierVector3refers to the class, not the constructor (except when you’re declaring the constructor, of course). And at first glance, you might think it means the same thing in a return type, because §3.4/3 (I’m using the C++11 standard here) saysDigging deeper, in §3.4.3.1/2,
The context of starting a declaration with an injected-class-name happens to be the same as in defining a constructor outside
class {}scope, a laThe older GCC noticed that the declaration wasn’t a constructor, then took a fallback path that did work. However that fallback was illegal because C++ specifies that in a context where the constructor could be the result of the lookup, it is the only valid lookup result.
In all probability, some user took the time to file a bug, and a GCC developer took the time to diagnose this, fix it, and write a testcase. Multiply across the number of trivialities in a complex language like C++, and you start to appreciate the effort put into your compiler.