[comp.lang.c++] Global Variable Constructors, Language design

kearns@read.columbia.edu (Steve Kearns) (09/07/89)

In C++, classes often do some initialization before the program
starts. It has been pointed out often in this newsgroup that C++ 
suffers because one cannot predict the order in which the various files
will be initialized.  However, one of the most serious ramifications
just hit me:

If a class, say class List, needs to do some initialization, then it
is UNSAFE to declare any global variable of type List, or any global
variable containing a List.  The global may be initialized before the 
List class is, probably causing serious problems.  

The only solution I can see is designing reusable classes that become
initialized when they are first called.  For example, every List constructor
would have to include a line like "if (! ListInited) ListInit();".
Yech.  Anybody have any other suggestions?

p.s. Is it safe to assume that the global variable definition 
"int Foo = 2; " will be initialized at compile time?

LANGUAGE DESIGN:

This points out two pet peeves.  I think that language designers should 
separate the definition of the abstract programming language from the
concrete implementation.  Programs are mathematical objects, which do not
live in FILES.  So I think that C++ should have been designed as assuming
that the whole program is in a single file.  Then the problem outlined 
above with class initialization could be avoided, using the C++ rule that
"global variables in 1 file are constructed from top to bottom."  The
issues dealing with separate compilation, while important, should be
treated in a second phase.  

Secondly, most languages we run into today still require "declaration before
use", i.e. before calling a function or accessing a variable it must have 
been declared previously in the file.  It seems to me that compilers should
be smart enough to handle definitions in any order.  Yes, it would require
more time and effort by the compiler, but it would be simpler for the user,
and more intuitive.

-steve
(kearns@cs.columbia.edu)

ttwang@polyslo.CalPoly.EDU (Thomas Wang) (09/08/89)

kearns@cs.columbia.edu writes:
>In C++, classes often do some initialization before the program
>starts. It has been pointed out often in this newsgroup that C++ 
>suffers because one cannot predict the order in which the various files
>will be initialized.  However, one of the most serious ramifications
>just hit me:

>If a class, say class List, needs to do some initialization, then it
>is UNSAFE to declare any global variable of type List, or any global
>variable containing a List.  The global may be initialized before the 
>List class is, probably causing serious problems.  

This is not quite it, but you came close.  Eg.

a::a()
{
  cout << "initing...\n";
}

static a an_object;

Now you are in trouble; 'cout' might be initialized after 'an_object' is
initialized.

>Yech.  Anybody have any other suggestions?

The solution is really complicated.  Say that you have a class caled
'type_car'.  Basically you want to get a list of global variables and static
variables one could ever use during type_car's construction phase.  Remove
from the list those variables that do not have constructors.  A global
variable of 'type_car' must be created after all those variables left in
the list are created.

The same operation goes for destructors too.  You want to get a list of
global variables and static variables one could ever use during type_car's
destruction phase.  Remove from the list those variables that do not have
destructors.  A global variable of 'type_car' must be destroyed after all
those variables in the list are destroyed.

>-steve

 -Thomas Wang ("I am, therefore I am."
                 - Akira               )

                                                     ttwang@polyslo.calpoly.edu