According to the C++
standard, calling a member function (in)directly of X
before all bases of X
are constructed results in undefined behaviour (draft n4910 §11.9.3 Initializing bases and members [class.base.init]/16). They provide following example:
class A {
public:
A(int);
};
class B : public A {
int j;
public:
int f();
B() : A(f()), // undefined behavior: calls member function but base A not yet initialized
j(f()) // well-defined: bases are all initialized
{}
};
What is the rationale behind this? I assume it results in undefined behavior in case f
would access a member of A
, because that member would not have been initialized yet. Are there other cases why this would result in undefined behaviour?
Edit:
I understand why in the given example the first call to f
is undefined behavior. However, I'm wondering what the rationale is for this. In other words: why is this defined as undefined behavior?
Assume that the definition of f
is as follows:
int B::f() {
return 0;
}
I would expect that this gets translated by most compilers to a function as follows:
int B::f(B *b) {
return 0;
}
This member function would never access any data member of B
. Hence, I wouldn't expect any undefined behaviour.
Now, consider f
has following definition:
int B::f() {
return this->j;
}
Which would get translated to something like this:
int B::f(B *b) {
return b->j;
}
This clearly accesses an uninitialized member of B
. Hence, undefined behaviour is expected.
To wrap it up: is the statement in the standard too general, or am I missing something and would both examples result in undefined behavior?