[comp.lang.c++] Static initialization

gkean@ccu1.aukuni.ac.nz (Graham Kean;;g_kean) (05/10/91)

Can anyone tell me why it is not possible to statically
initialize an instance of a class containing virtual functions?

Both Zortech C++ and Borland C++ give an error at the
'{1,2,3}' in the following example:

class TESTCLASS
    {
    public:
	int a,b,c;
	virtual void testfunc();
    };
void TESTCLASS::testfunc() {}
TESTCLASS test = {1,2,3};

I realize that there will be a 'hidden' instance variable, being
a pointer to the virtual function table, but I can't quite grasp
why the compiler can't generate it.  (The example works fine when
testfunc() is not virtual).

steve@taumet.com (Stephen Clamage) (05/12/91)

gkean@ccu1.aukuni.ac.nz (Graham Kean;;g_kean) writes:

>Both Zortech C++ and Borland C++ give an error at the
>'{1,2,3}' in the following example:

>class TESTCLASS
>    {
>    public:
>	int a,b,c;
>	virtual void testfunc();
>    };
>void TESTCLASS::testfunc() {}
>TESTCLASS test = {1,2,3};

The C++ rule is that a class may be statically intialized using C-style
initialization syntax as long as it doesn't have "class-like" features.
Class-like features require a constructor to be called, which is not
supported by the C syntax.  You can look up in the ARM to find the
full details of what is allowed.  The easiest way to remember it is that
a class can be initialized with C syntax if it looks like a C struct.
Otherwise, use a constructor.  (This is overly restrictive, but will
keep you out of trouble.)

In your specific instance, a class with virtual functions requires a
(pointer to the) table of the virtual functions to be part of the class,
something done by the constructor.  The '={1,2,3}' syntax precludes
calling a contructor, and hence is illegal.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

jimad@microsoft.UUCP (Jim ADCOCK) (05/15/91)

In article <1991May10.063358.15955@ccu1.aukuni.ac.nz> gkean@ccu1.aukuni.ac.nz (Graham Kean;;g_kean) writes:
|Can anyone tell me why it is not possible to statically
|initialize an instance of a class containing virtual functions?
|
|class TESTCLASS
|    {
|    public:
|	int a,b,c;
|	virtual void testfunc();
|    };
|void TESTCLASS::testfunc() {}
|TESTCLASS test = {1,2,3};

The problem is not that you are trying to statically initialize an
instance of a class containing virtual functions, but rather that
you are trying to initialize a class with virtual functions with
an initializer list.  ARM 8.4.1 states that you are only allowed
to use initializer lists with objects of classes with no constructors,
no private nor protected members, no bases classes, nor any virtual 
functions.  I don't see where there would be any great difficulty for
most compilers to statically initialize your vtable pointer, its
just that the standard tells them not to do so.

I'd guess the rationale is that if you want to be using inheritence
and polymophism, you really "ought" to be be doing it the C++ way,
using constructors to get your object to a safe default state,
and then use member functions to modify that state.  Alternatively,
for C backwards compatibility with C-like structures, C++ still
supports initializer lists.  Compilers could be required to support
strategies that fall in between, but I guess it wasn't considered
worthwhile.  With the present rules, compiler writers are assured that
all vtable ptr initializations can happen within compiler generated
constructors.  Your desired feature would require them to be a little
bit smarter.