[Search for users]
[Overall Top Noters]
[List of all Conferences]
[Download this site]
Title: | C++ |
Notice: | Read 1.* and use keywords (e.g. SHOW KEY/FULL KIT_CXX_VAX_VMS) |
Moderator: | DECCXX::AMARTIN |
|
Created: | Fri Nov 06 1987 |
Last Modified: | Thu Jun 05 1997 |
Last Successful Update: | Fri Jun 06 1997 |
Number of topics: | 3604 |
Total number of notes: | 18242 |
3529.0. "Initialize problem" by HLFS00::JONGH_D (Daan de Jongh) Mon Apr 07 1997 12:29
Hi,
A customer has a problem with the string type. In some cases (see
example) it causes a failure while intializing a class type.
He provided me with an example which I stripped down to the smallest
size which reproduced the problem. The sources are in this notes-entry,
but also available at UTRTSC::LOG80789.BCK. A MMS-script is included.
The C++ syntax looks good to me.
Is this a syntax problem or a bug?
The error occurs, when uses is declared.
Daan
====================== ERROR =========================================
$ run/nodebug uses_boom
in const char* constructor
Nest::Nest()
in const char* constructor
in const char* constructor
Nest::Nest()
Used::Used(), s="i am used"
in const char* constructor
%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual
address=000000000000
0000, PC=FFFFFFFF8090E758, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs
PC
0 0000000000000000
FFFFFFFF8090E758
USES_BOOM USED basic_string__6 12688 0000000000001214
0000000000035364
USES_BOOM USED Used__2 15177 00000000000015F4
0000000000035744
USES_BOOM USES Uses__1 15206 00000000000014EC
0000000000033D3C
USES_BOOM U_MAIN __init_U_MAINBBFF84
15207 0000000000001514
0000000000031514
USES_BOOM 0 0000000000029480
0000000000039480
0 FFFFFFFF86E1F0D8
FFFFFFFF86E1F0D8
================== SOURCES ===========================================
! ***BOF***
!
! descrip.mms
!
!==============================================================================
! Test files
!==============================================================================
! Paths
src=[]
inc=[]
lib=[]
obj=[]
rep=([.cxx_repository])
!
cpp=cxx
ln=cxxlink
ar=lib
!
.ifdef nodbg
cflags=/obj=$(obj)
.else
cflags=/debug/obj=$(obj)/define=(DEBUG)
.endif
cppflags=/assume=(noheader)/exc/template_define=(auto)
!
.ifdef nodbg
lnflags=/log/syslib/repo=$(rep)
.else
lnflags=/debug/log/syslib/repo=$(rep)
.endif
!
arflags=/insert
selflag=/selective_search
!
!------------------------------------------------------------------------------
!
.cxx.obj
$(cpp) $(cflags) $(cppflags) $?
!------------------------------------------------------------------------------
! main targets
all : boom
- run/nodebug uses_boom
!
boom : $(obj)u_main.obj $(lib)uses.obj $(lib)used.obj $(lib)nest.obj
$(ln)$(lnflags)/exe=uses_boom -
$(obj)u_main.obj,-
$(obj)uses.obj,-
$(obj)used.obj,-
$(obj)nest.obj
!
!
clean :
- purge
- del *.exe;*
- del *.obj;*
!------------------------------------------------------------------------------
! subtargets
$(obj)u_main.obj : $(src)u_main.cxx
$(obj)u_init.obj : $(src)u_init.cxx
$(obj)uses.obj : $(src)uses.cxx
$(obj)used.obj : $(src)used.cxx
$(obj)nest.obj : $(src)nest.cxx
! ***EOF***
// ***BOF***
//=====================================================================
// u_main.cxx
// -------------------------------------------------------------------
// Copyright (c) 1997 ECT B.V. All Rights Reserved.
// -------------------------------------------------------------------
// Uses program
//=====================================================================
#include <stdlib.h>
#include "uses.h"
Nest nest;
Used used;
Uses uses;
int main(int, char*[])
{
return EXIT_SUCCESS;
}
// ***EOF***
// ***BOF***
//=====================================================================
// uses.cxx
// -------------------------------------------------------------------
// Copyright (c) 1997 ECT B.V. All Rights Reserved.
// -------------------------------------------------------------------
// This class uses another one
//=====================================================================
#include "uses.h"
Uses::Uses()
: u(nil_Used),
s("i am uses")
{
cout << "Uses::Uses(), s=\"" << s << "\"" << endl;
}
Uses::Uses(const Uses& that)
: u(that.u),
s(that.s)
{
}
Uses& Uses::operator=(const Uses& that)
{
if (this != & that)
{
u = that.u;
s = that.s;
}
return *this;
}
Uses::~Uses()
{}
Used Uses::InUse() const
{
return u;
}
ostream& operator<<(ostream& ostr, const Uses& object)
{
object.printOn(ostr);
return ostr;
}
void Uses::printOn(ostream& ostr) const
{
ostr << "Uses(" << s << ") contains_a " << u;
}
// ***EOF***
// ***BOF***
//=====================================================================
// uses.h
// -------------------------------------------------------------------
// Copyright (c) 1997 ECT B.V. All Rights Reserved.
// -------------------------------------------------------------------
// This class uses another one
//=====================================================================
#ifndef __uses_h
#define __uses_h
#include <iostream>
#include "used.h"
class Uses
{
public:
Uses();
Uses(const Uses& that);
Uses& operator=(const Uses& that);
virtual ~Uses();
Used InUse() const;
friend ostream& operator<<(ostream& ostr, const Uses& object);
protected:
virtual void printOn(ostream& ostr) const;
private:
string s;
Used u;
};
#endif // __uses_h
// ***EOF***
// ***BOF***
//=====================================================================
// used.cxx
// -------------------------------------------------------------------
// Copyright (c) 1997 ECT B.V. All Rights Reserved.
// -------------------------------------------------------------------
// This class used another one
//=====================================================================
#include "used.h"
const Used nil_Used;
Used::Used()
: n(),
s("i am used")
{
cout << "Used::Used(), s=\"" << s << "\"" << endl;
}
Used::Used(const Used& that)
: n(that.n),
s(that.s)
{}
Used& Used::operator=(const Used& that)
{
if (this != & that)
{
n = that.n;
s = that.s;
}
return *this;
}
Used::~Used()
{}
ostream& operator<<(ostream& ostr, const Used& object)
{
object.printOn(ostr);
return ostr;
}
void Used::printOn(ostream& ostr) const
{
ostr << "Used(" << s << ") contains_a " << n;
}
// ***EOF***
// ***BOF***
//=====================================================================
// used.h
// -------------------------------------------------------------------
// Copyright (c) 1997 ECT B.V. All Rights Reserved.
// -------------------------------------------------------------------
// This class is used by another one
//=====================================================================
#ifndef __used_h
#define __used_h
#include <iostream>
#include "nest.h"
class Used
{
public:
Used();
Used(const Used& that);
Used& operator=(const Used& that);
virtual ~Used();
friend ostream& operator<<(ostream& ostr, const Used& object);
protected:
virtual void printOn(ostream& ostr) const;
string s;
Nest n;
};
extern const Used nil_Used;
#endif // __used_h
// ***EOF***
// ***BOF***
//=====================================================================
// nest.cxx
// -------------------------------------------------------------------
// Copyright (c) 1997 ECT B.V. All Rights Reserved.
// -------------------------------------------------------------------
// This class nest another one
//=====================================================================
#include "nest.h"
//const Nest nil_Nest;
Nest::Nest()
: s("i am nest")
{
cout << "Nest::Nest()" << endl;
}
Nest::Nest(const string& value)
: s(value)
{}
Nest::Nest(const Nest& that)
: s(that.s)
{}
Nest& Nest::operator=(const Nest& that)
{
if (this != &that)
{
s = that.s;
}
return *this;
}
Nest::~Nest()
{}
ostream& operator<<(ostream& ostr, const Nest& object)
{
object.printOn(ostr);
return ostr;
}
void Nest::printOn(ostream& ostr) const
{
ostr << "Nest(" << s << ")";
}
// ***EOF***
// ***BOF***
//=====================================================================
// nest.h
// -------------------------------------------------------------------
// Copyright (c) 1997 ECT B.V. All Rights Reserved.
// -------------------------------------------------------------------
// This class is nest by another one
//=====================================================================
#ifndef __nest_h
#define __nest_h
#include <iostream>
#include <string>
class Nest
{
public:
Nest();
Nest(const string& value);
Nest(const Nest& that);
Nest& operator=(const Nest& that);
virtual ~Nest();
friend ostream& operator<<(ostream& ostr, const Nest& object);
protected:
virtual void printOn(ostream& ostr) const;
private:
string s;
};
#endif // __nest_h
// ***EOF***
T.R | Title | User | Personal Name | Date | Lines |
---|
3529.1 | | SPECXN::DERAMO | Dan D'Eramo | Mon Apr 07 1997 13:06 | 44 |
| > Nest nest;
> Used used;
> Uses uses;
The objects named "nest", "used", and "uses" will be
constructed in that order. Since the default constructor of
class Uses refers to the global const object named "nil_Used",
object "nil_Used" must be constructed before object "uses" if
the program is going to work.
> $ run/nodebug uses_boom
> in const char* constructor
> Nest::Nest()
> in const char* constructor
> in const char* constructor
> Nest::Nest()
> Used::Used(), s="i am used"
> in const char* constructor
> %SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual
> address=000000000000
> 0000, PC=FFFFFFFF8090E758, PS=0000001B
Only one object of class Used is being constructed before the
object named "uses" is constructed. Since an object of class
"Nest" was constructed before that, I would say the
construction order was
nest
used
uses
nil_Used
except that there was an access violation during the
construction of "uses" because its construction referred to
"nil_Used" but "nil_Used" had not been constructed yet.
I'd have to put on my language lawyer hat :-) and go back and
read the appropriate sections of the ARM or the latest DWP to
see if it was up to the programmer to take steps to insure the
proper order of construction here vs. whether this was a case
where the compiler was required to construct "nil_Used"
earlier.
Dan
|
3529.2 | initialization order rules | DECC::J_WARD | | Mon Apr 07 1997 14:01 | 6 |
|
I believe there is no guarantee in C++ about the order of initialization
of global objects defined in different translation units.
Within the same translation unit, the order of initialization is
in the same order as the definition appears.
|
3529.3 | Manual is not clear | HLFS00::JONGH_D | Daan de Jongh | Mon Apr 28 1997 06:55 | 27 |
|
I think the ARM manual is not clear on this point.
In section 3.4 is the following:
"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 my 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. The default initialization of all static objects
to zero is performed before any dynamic (that is, run-time)
initialization. No further order is imposed on the initialization
of objects from different translation units."
But in section 12.1 is the following:
"If a class has a constructor, each object of that class will be
initialized before any use is made of the object; see 12.6."
This sentence states that the object should be initialized before it is
used, or am I reading this wrong?
Does anyone know how to interpret this?
Daan
|