[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::c_plus_plus

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 15: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.RTitleUserPersonal
Name
DateLines
3529.1SPECXN::DERAMODan D'EramoMon Apr 07 1997 16:0644
> 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.2initialization order rulesDECC::J_WARDMon Apr 07 1997 17:016
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.3Manual is not clear HLFS00::JONGH_DDaan de JonghMon Apr 28 1997 09:5527
                                     
    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