[comp.sys.apollo] Is this a bug in Apollo C++ Compiler System?

ashley@usage.csd.oz (Ashley Aitken) (06/25/91)

C++ Compiler System Bug Report?
===============================

Overview:

Not all constructors and destructors for global (and static) 
objects (in separated source files) are called before the 
start of the main program. Those called depend on the
order of linking of the object files.

Cause?

I believe that the error is caused by failure of the start-
up initialization code in the _entry routine, or more likely
failure of the Constructor Linker.     

Technical:
On observation of the C code generated it seems that the 
correct STI and STD functions and LINK structures are 
being created for each file but not being linked 
together or called correctly. 

c++patch / mxx ?

Compiler:
Error seems to be common to both Version 1.2.1 and Version
2.0 of the C++ Compiler (Glockenspiel) on HP-Apollo Domain
machines. 

ld : C Compilation System, Issue 4.0 (11.0) 1/3/86 : Version 1.8.2.1: 11/19/85


Example
	Source Files (appended to document):
		file1.cxx
		file2.cxx

	Compilation:
		CC -c file1.cxx
		CC -c file2.cxx

	CC -o testa file1.o file2.o  
 
        Output From testa:

		Construtor C
		Construtor D
		Start Main
		A::m1
		Construtor B
		D::m1
		End   Main
		Destructor B
		Destructor D
		Destructor C


Constructor (and Destructor) for a of class A is not called 		
at all!
            
	CC -o testa file2.o file1.o  
           
	Output from testb:

		Construtor A
		Start Main
		A::m1
		Construtor B
		D::m1
		End   Main
		Destructor B
		Destructor A     

Constructor (and Destructor) for c of class C and d of class
D are not called at all!  

file1.cxx:

#include	<stream.h>
                       

class A {
public:
	 A();      
	 void m1();
	~A();
};  

A::A()  { cout << "Construtor A\n"; } 
void A::m1() { cout << "A::m1\n"; }
A::~A() { cout << "Destructor A\n"; }
 
A a;


class B {
public:
	 B();   
	~B();
};  

B::B()  { cout << "Construtor B\n"; }
B::~B() { cout << "Destructor B\n"; }
   
 
class D {
public:
	 D();
	 void m1();   
	~D();
};  
   
extern D d;

main () {

	cout << "Start Main\n"; 
	a.m1();
	B b; 
	d.m1();
	cout << "End   Main\n";

}

*EOF*

file2.cxx:

#include	<stream.h>

class C {
public:
	 C();   
	~C();
};  

C::C()  { cout << "Construtor C\n"; }
C::~C() { cout << "Destructor C\n"; }
 
static C c;


class D {
public:
	 D(); 
	 void m1();  
	~D();
};  

D::D()  { cout << "Construtor D\n"; }
void D::m1() { cout << "D::m1\n"; }
D::~D() { cout << "Destructor D\n"; }
   
D d;

*EOF*
      
Originator:                 

Ashley Aitken    

School of Electrical Engineering and Computer Science
University of New South Wales 

ashley@spectrum.cs.unsw.oz.au
Ph (02) 663-8117 (Answering)
24th June, 1991.

dsouza@gwen.cad.mcc.com (Desmond Dsouza) (06/25/91)

In article <1801@usage.csd.unsw.oz.au> ashley@usage.csd.oz (Ashley Aitken) writes:

   Not all constructors and destructors for global (and static) 
   objects (in separated source files) are called before the 
   start of the main program. Those called depend on the
   order of linking of the object files.

Global objects do NOT have to be constructed before main() is 
entered. The language simply requires that such globals be 
constructed
	 "... before the first use of any function or object defined
	in THAT translation unit". 

An implementation is free to defer initialization until that time (see
ARM, Sec. 3.4).

Can someone clarify the ARM definition for me, please. Is it the case
that I can freely refer to global objects defined in any other files
and be assured that they are initialized before they are first
accessed? 

--
Desmond.
--

-------------------------------------------------------------------------------
 Desmond D'Souza, MCC CAD Program | ARPA: dsouza@mcc.com | Phone: [512] 338-3324
 Box 200195, Austin, TX 78720 | UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!dsouza

vasta@apollo.hp.com (John Vasta) (06/28/91)

In article <1801@usage.csd.unsw.oz.au> ashley@spectrum.cs.unsw.oz.au (Ashley Aitken) writes:
>C++ Compiler System Bug Report?
>===============================
>
>Overview:
>
>Not all constructors and destructors for global (and static) 
>objects (in separated source files) are called before the 
>start of the main program. Those called depend on the
>order of linking of the object files.

This is a true statement, and is not in conflict with the definition
of the C++ language, as Desmond D'Souza in
<DSOUZA.91Jun25115711@gwen.cad.mcc.com> pointed out. Section 3.4 of
"The Annotated C++ Reference Manual", by Stroustrup and Ellis, is
pretty clear on this.

Now, your example shows that a constructor/destructor execution is
simply missing.  I tried your example with both Domain/C++ V2.0.0 and
V2.1.0, and cannot reproduce your results - all constructors and
destructors executed correctly.

I had sent you private mail on this subject; I received no response so
I'm not sure if you got my mail. But your problem sounds suspiciously
like what will happen if you start using the latest release of the
Domain/C compiler (V6.8) with C++ before V2.1.0. The C compiler now
compresses data sections by default, and that messes up the C++
"constructor linker". This is described in the C release notes along
with a workaround - use "-W0,-ncompress" to get the old behavior. The
C++ 2.1.0 release fixes the problem so that you can use the compressed
data feature.

-- 
John Vasta                Hewlett-Packard Apollo Systems Division
vasta@apollo.hp.com       M.S. CHR-03-DW
(508) 256-6600 x5978      300 Apollo Drive, Chelmsford, MA 01824
UUCP: {decwrl!decvax, mit-eddie, attunix}!apollo!vasta