Re: Is this code snippet undefined behavior?
On 8/22/2012 4:25 PM, davidg@kixeye.com wrote:
class A
{
public:
A(int x);
...
Amethod();
};
class B
{
public:
B() : a_ref(a), a(42) { }
...
Bmethod() { a_ref.Amethod(); }
...
private:
A &a_ref;
A a;
};
Since the standard states that initializers are executed in the
order given in the class definition, this means a_ref is initialized
before a, and yet a_ref is trying to reference a.
Not sure what you mean by "yet a_ref is trying to reference a". The
initialization of a reference does not need the value, it does not touch
the value. Essentially it makes sure that when you use 'a_ref'
variable, it will be *as if* you actually used 'a', that's all
*references* are for.
The *object* designated by the 'a' member is not initialized until after
a reference to it is obtained. Undefined behavior? Not sure. I think
it's implementation-defined, but doesn't have to be documented.
The reason I ask is that I found the same pattern in the source to
the latest Mongodb C++ drivers, and when compiled with GCC it will
sometimes wind up leaving a_ref referencing a NULL pointer.
You seem to be saying that GCC implements references as pointers, gives
them storage, and in this particular case using 'a_ref' is like
dereferencing a null pointer because it's initialized with an object
that itself hasn't been initialized. <shrug> So?
Implementation-defined, just like all references.
What I mean by that is when B::Bmethod calls a_ref.Amethod(), if I
single step from B::Bmethod() into A::Amethod() and inspect "this",
it's NULL.
That's a QoI issue, I believe. And my opinion of GCC's QoI is not very
high.
Some other compiler *may* do it differently. Although the 'a' object
has not been initialized, the *storage* for it has already been
allocated, and, if your references are pointers behind the scenes, you
can figure out the address of 'a' and initialize 'a_ref' with it even
though the storage itself hasn't been properly run through a constructor
yet. QoI.
V
--
I do not respond to top-posted replies, please don't ask