From: adk@Warren.MENTORG.COM (Ajay Kamdar)
Subject: initialization of static data
Summary: are my compilers broken as I believe they are?
Organization: Mentor Graphics Corp. - IC Group
Date: Fri, 31 Jul 1992 19:37:46 GMT


I have run into a problem with initialization of static data in multiple
translation units. This is despite my attempts to only do what is legal
as specified by ARM.

On pg. 19, $3.4, ARM states:
	The initialization of nonlocal static objects in a translation
	unit is done before the first use of any function or object defined
	in that translation unit. Such initializations may be done before
	the first statement of main() or deferred to any point in time before
	the first use of a function or object defined in that translation unit.

I believe that my compilers (Sun C++ 2.1, AT&T C++ 3.0)  don't seem to
follow this rule. However, given the tricky nature of this whole issue,
I would very much appreciate input from the net as to whether my
interpretation of ARM on how this stuff should work is incorrect, or
whether cfront is broken. If you agree that the compiler is indeed
broken, suggestions on how to workaround the problem would be very
welcome. However, while making suggestions, please keep in mind that the
real life code on which this example is based is much more complex than
what I have shown here.

I have distilled the problem to a very simple test example consisting
of 3 files: t.c, a.c, and b.c. Both a.c and b.c contain static objects.
The initialization of static objects in b.c starts first. However,
from within the CTOR for the static object in b.c, I call a function
defined in the file a.c. My interpretation of the ARM suggests to me
that this should force the initilization of the static objects in a.c
before the function is executed. However, as the example below demonstrates,
things do not quite proceed as I expect them to.

Compiling and executing my test programs results in the following output:

dre:/home/adk/tmp 431% CC t.c a.c b.c
CC  t.c:
CC  a.c:
CC  b.c:
cc  -L/usr/lang/ATT_3.0/lib   t.c a.c b.c -lC
t.c:
a.c:
b.c:
dre:/home/adk/tmp 432% a.out
a.d_val == 0
setting a.d_val = 5
a.d_val == 5
B()
a.d_val == 5
setting a.d_val = 5
a.d_val == 5
B()
A()
a.d_val == 1

As the output shows, the static object in a.c is not initialized before a
function defined in a.c is executed. This result was obtained with the
following source code:

/*
File: t.c
*/

extern void printStaticAVal();
extern void fnInB();

main()
{
	fnInB();	// call function in b.c
				// should cause initialization of statics in B
				// if not already done before start of main()

	printStaticAVal(); // print the value of the static in a.c
}

/*
File: a.c
*/

#include <iostream.h>

class A {
public:
	int	d_val;
	A(int i) : d_val(i) {cout << "A()" << endl;}
};

static A	a(1);

void setStaticValInA()
{
	cout << "a.d_val == " << a.d_val << endl;
	cout << "setting a.d_val = 5" << endl;
	a.d_val = 5;
	cout << "a.d_val == " << a.d_val << endl;
}

void printStaticAVal() {cout << "a.d_val == " << a.d_val << endl;}

/*
File: b.c
*/

#include <iostream.h>

extern void setStaticValInA();
	// function defined in a.c.
	// calling this function should cause the initialization of
	// all non local static data in a.c before the first use of this
	// function

class B {
public:
	B()
	{
		setStaticValInA();
			// ensure that static data in A is initialized
		cout << "B()" << endl;
	}
};

static B	b1;
static B	b2;

void fnInB() {}
	// function called from main() to initialize b.c's static data
	// in case data not initialized before start of main()
-- 
I speak for none but myself.

Ajay Kamdar                               Email : ajay_kamdar@mentorg.com
Mentor Graphics, IC Group (Warren, NJ)    Phone : (908) 580-0102
Newsgroups: comp.lang.c++