Topic: ARM ambiguity about member initializers and virtual functions
Author: ellis@parc.xerox.com (John Ellis)
Date: 27 Jan 93 00:45:05 GMT Raw View
For the purposes of binding virtual functions, is a member initializer
considered part of the constructor in which it appears? The answer
might seem obviously yes, but the ARM appears contradictory on this point.
Consider this test program:
#include <iostream.h>
struct A {
A() {f();}
virtual int f() {
cout << "In A::f.\n";
return 0;}
int g() {return f();}};
struct B: A {
B(): i( g() ) {g();}
int i;
virtual int f() {
cout << "In B::f.\n";
return 0;}};
void main() {B b;}
Three compilers we tested believe that member initializers are part of a
constructor as regards virtual functions. They produced this output:
In A::f.
In B::f.
In B::f.
whereas a fourth compiler, known for its rigid adherence to the
standard, has a contrary belief:
In A::f.
In A::f.
In B::f.
The natural interpretation, that a member initializer is part of its
constructor, comes from two passages in the ARM:
Page 294, 12.7: Member functions may be called in constructors and
destructors. ... The function called will be the one defined in
the constructor's (or destructor's) own class or its bases, but
*not* any function overriding it in a derived class.
Page 294, 12.6.2: A mem-initializer is evaluated in the scope of
the constructor in which it appears.
But some earlier commentary clearly contradicts the natural
interpretation:
Page 233, 10.9c: When B::B() is executing, the C part of the
object being constructed exists only as raw storage and cannot be
accessed through a virtual function. The available f() is A::f().
The first point at which C::f() can be called as f() is the first
*statement* in the constructor C::C(). [emphasis added]
This clearly states that a class's virtual functions are not available
before the first statement of a constructor. Since member
initializers are executed before the statements of the constructor:
Page 292, 12.6.2: ...then the members are initialized...then the
body of D::D() is executed (12.1).
this implies that a class's virtual functions are not available to a
member initializer.
Is section 10.9c wrong?