Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug
Bug#: 10112
Product:  
Component:  
Status: NEW
Resolution:
Assigned To: Not yet assigned to anyone <unassigned@gcc.gnu.org>
Host:
Reported against  
Priority:  
Severity:  
Target Milestone:  
 
 
Target:
Reporter: o.kullmann@swansea.ac.uk
Add CC:
CC:
Remove selected CCs
Build:
URL:
Summary:
Keywords:
Known to work:
Known to fail:

Attachment Description Type Created Size Actions
FehlerInit.cpp FehlerInit.cpp text/x-c++ 2003-05-21 15:17 521 bytes Edit
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 10112 depends on: Show dependency tree
Show dependency graph
Bug 10112 blocks:

Additional Comments:





Mark bug as waiting for feedback
Mark bug as suspended




View Bug Activity   |   Format For Printing   |   Clone This Bug


Description:   Last confirmed: 2005-12-18 20:06 Opened: 2003-03-16 20:06
When compiling the attached file (56 lines) with

> g++ FehlerInit.cpp

and running it I get

> ./a.out
-33630626
Speicherzugriffsfehler

The first line in main
LitIntOccInt::Var v;
yields a call of the member function
InfoPolicyVector<int>::new_variable()
which prints out the iterator difference between
centre and info_vector.begin(), where
centre is a static data member initialised to
info_vector.begin(),
and thus the result should be 0, but as shown
above, it is "undefined".

The code given seems to be a minimal example
(up to some typedefs) in the sense, that removing
any other stuff (which seems completely unrelated
to the above behaviour) changes the output to
the correct "0".

Release:
gcc 3.2.1

Environment:
> g++ -v
Reading specs from /compsci/partition1/csoliver/GCC/gcc-3.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/specs
Configured with: /compsci/partition1/csoliver/GCC/gcc-3.2.1/configure --enable-threads=posix --enable-long-long --prefix=/compsci/partition1/csoliver/GCC/gcc-3.2.1 --with-local-prefix=/compsci/partition1/csoliver/GCC/Include_3.2.1 --enable-languages=c,c++ --disable-nls --enable-shared
Thread model: posix
gcc version 3.2.1

How-To-Repeat:
Compile and run.

------- Comment #1 From o.kullmann@swansea.ac.uk 2003-03-16 20:06 -------
Fix:
I have no idea. It seems to me quite serious.

P.S. Perhaps it would be a good idea to somehow
improve the instructions for submitting a bug.
For example I couldn't find an explanation of
what the above abbreviations for the error class
could mean.

------- Comment #2 From Giovanni Bajo 2003-03-16 23:22 -------
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: <gcc-gnats@gcc.gnu.org>,
	<gcc-bugs@gcc.gnu.org>,
	<nobody@gcc.gnu.org>,
	<O.Kullmann@Swansea.ac.uk>,
	<gcc-prs@gcc.gnu.org>
Cc:  
Subject: Re: c++/10112: static data member is not correctly initialised
Date: Sun, 16 Mar 2003 23:22:30 +0100

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p
 r=10112
 
 Confirmed with 3.2, cygwin on x86. Reduced snippet is:
 
 ----------------------------------
 #include <cassert>
 using namespace std;
 
 struct A
 {
  int p;
 
  A(int _p) : p(_p)
  {}
 };
 
 template <typename T>
 struct B
 {
   static A a;
   static int p1;
 };
 
 
 template <typename T> A B<T>::a(123);
 template <typename T> int B<T>::p1 = a.p;
 
 int main()
 {
  // Should not assert, but it does
  assert(B<int>::p1 == B<int>::a.p);
 }
 ----------------------------------
 
 Looking at the generated code on x86, it seems that the two variables are
 initialized in reversed order:
 
 00401104 <__Z41__static_initialization_and_destruction_0ii>:
     [....]
   401139: a1 b0 e8 40 00        mov    0x40e8b0,%eax
   40113e: a3 a0 e8 40 00        mov    %eax,0x40e8a0
     [....]
   401172: c7 04 24 b0 e8 40 00  movl   $0x40e8b0,(%esp,1)
   401179: c7 44 24 04 7b 00 00  movl   $0x7b,0x4(%esp,1)
   401180: 00
   401181: e8 9a 47 00 00        call   405920 <__ZN1AC1Ei>
 
 00405920 <__ZN1AC1Ei>:
   405920: 55                    push   %ebp
   405921: 89 e5                 mov    %esp,%ebp
   405923: 8b 55 08              mov    0x8(%ebp),%edx
   405926: 8b 45 0c              mov    0xc(%ebp),%eax
   405929: 89 02                 mov    %eax,(%edx)
   40592b: 5d                    pop    %ebp
   40592c: c3                    ret
 
 
 The code at 401139 copies B<T>::a.p into B<T>::p1 (it's the initialization
 of B<T>::p1), while the second block initializes B<T>::a.p with 123 (0x7b),
 but it's too late. I tried with no optimization, and -O0/1/2/3 and there is
 no difference, the code is always wrong.
 
 As for the standard, §9.4.2p7 says <<Static data members are initialized and
 destroyed exactly like nonlocal objects (3.6.2, 3.6.3).>>. §3.6.2p1 says:
 <<Objects of POD types (3.9) with static storage duration initialized with
 constant expressions (5.19) shall be initialized before any dynamic
 initialization takes place. Objects with static storage duration defined in
 namespace scope in the same translation unit and dynamically initialized
 shall be initialized in the order in which their definition appears in the
 translation unit.>>. Now, B<T>::p1 is a POD type but it is not initialized
 with a constant expression, so I don't see any reason why it should be
 initialized before B<T>::a.
 
 Giovanni Bajo
 

------- Comment #3 From Nathan Sidwell 2003-03-17 12:04 -------
State-Changed-From-To: open->analyzed
State-Changed-Why: the ordering of these two template instantiations is implementation defined. I think there's an algorithm to get
    the order right
    
    nathan

------- Comment #4 From Wolfgang Bangerth 2003-03-17 18:15 -------
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: giovannibajo@libero.it, <gcc-gnats@gcc.gnu.org>, <gcc-bugs@gcc.gnu.org>,
   <o.kullmann@swansea.ac.uk>, <nathan@gcc.gnu.org>
Cc:  
Subject: Re: c++/10112: static data member is not correctly initialized
Date: Mon, 17 Mar 2003 18:15:06 -0600 (CST)

 I think with this code, A::p1 is statically initialized (being a POD 
 type), while B::a is dynamically initialized (having a user-defined 
 constructor). I think I remember that the standard specifies that static 
 initializers always run before dynamic ones, irrespective of the order in 
 which they appear in the source file. In that case, this would not be a 
 bug.
 
 W.
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth             email:            bangerth@ticam.utexas.edu
                               www: http://www.ticam.utexas.edu/~bangerth/
 
 


------- Comment #5 From o.kullmann@swansea.ac.uk 2003-03-17 18:49 -------
From: Oliver Kullmann <O.Kullmann@Swansea.ac.uk>
To: nathan@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org,
   nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: c++/10112: static data member is not correctly initialised
Date: Mon, 17 Mar 2003 18:49:06 +0000

 On Mon, Mar 17, 2003 at 12:04:17PM -0000, nathan@gcc.gnu.org wrote:
 > Date: 17 Mar 2003 12:04:17 -0000
 > To: O.Kullmann@Swansea.ac.uk, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org,
 >    nobody@gcc.gnu.org
 > From: nathan@gcc.gnu.org
 > Reply-To: nathan@gcc.gnu.org, O.Kullmann@Swansea.ac.uk, gcc-bugs@gcc.gnu.org,
 >    gcc-prs@gcc.gnu.org, nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org
 > X-Mailer: gnatsweb 2.9.3
 > Subject: Re: c++/10112: static data member is not correctly initialised
 > X-Spam-Status: No, hits=-99.3 required=8.0
 > 	tests=NO_REAL_NAME,USER_IN_WHITELIST
 > 	version=2.50
 > X-Spam-Level: 
 > X-Spam-Checker-Version: SpamAssassin 2.50 (1.173-2003-02-20-exp)
 > 
 > Synopsis: static data member is not correctly initialised
 > 
 > State-Changed-From-To: open->analyzed
 > State-Changed-By: nathan
 > State-Changed-When: Mon Mar 17 12:04:17 2003
 > State-Changed-Why:
 >     the ordering of these two template instantiations is implementation defined. I think there's an algorithm to get
 >     the order right
 >     
 >     nathan
 > 
 > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=10112
 
 Hi,
 
 (I hope that's the right way to reply?!)
 
 hmhm, might be. I guess the relevant sentence is
 
 in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
 
 (section 14.7.1 of ISO/IEC 14882:1998(E)),
 
 and thus one could conclude that in Giovanni's example in the instruction
 
 assert(B<int>::p1 == B<int>::a.p);
 
 the order of initialisations depends on the order of evaluation of the equality
 expression, which is implementation defined.
 
 Is this the interpretation?!
 
 The best solution (which might also be a better design) seems to me, to put the
 static data member (in the example, of class B) into a new (local) class X (or struct),
 for which we provide a constructor guaranteeing the right order of initialisation. 
 The host class B then has one static data member of type X. When we first use this
 data member, it will be constructed using the right order of initialisation.
 
 Sounds okay to me. (Worked in my case.)
 
 Thanks for your help!
 
 Oliver
 
 -- 
 Dr. Oliver Kullmann
 Computer Science Department
 University of Wales Swansea
 Faraday Building, Singleton Park
 Swansea SA2 8PP, UK
 http://cs-svr1.swan.ac.uk/~csoliver/
 


------- Comment #6 From Giovanni Bajo 2003-03-18 02:36 -------
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: "Wolfgang Bangerth" <bangerth@ticam.utexas.edu>,
	<gcc-gnats@gcc.gnu.org>,
	<gcc-bugs@gcc.gnu.org>,
	<o.kullmann@swansea.ac.uk>,
	<nathan@gcc.gnu.org>
Cc:  
Subject: Re: c++/10112: static data member is not correctly initialized
Date: Tue, 18 Mar 2003 02:36:55 +0100

 ----- Original Message -----
 From: "Wolfgang Bangerth" <bangerth@ticam.utexas.edu>
 To: <giovannibajo@libero.it>; <gcc-gnats@gcc.gnu.org>;
 <gcc-bugs@gcc.gnu.org>; <o.kullmann@swansea.ac.uk>; <nathan@gcc.gnu.org>
 Sent: Tuesday, March 18, 2003 1:15 AM
 Subject: Re: c++/10112: static data member is not correctly initialized
 
 Wolfgang, objects of POD types are statically initiliazed if and only if the
 initiliazer is constant, and that's not the case of the above snippet. This
 is very clear in §3.6.2p1, which I quoted (it's the same paragraph that
 introduces the concept of "static initialization" and "dynamic
 initalization"). Since my quote was maybe confusing because stripped down to
 the minimum, I post the full paragraph:
 
 -------------------
 The storage for objects with static storage duration (3.7.1) shall be
 zeroinitialized (8.5) before any other
 initialization takes place. Zeroinitialization and initialization with a
 constant expression are collectively
 called static initialization; all other initialization is dynamic
 initialization. Objects of POD types (3.9) with
 static storage duration initialized with constant expressions (5.19) shall
 be initialized before any dynamic
 initialization takes place. Objects with static storage duration defined in
 namespace scope in the same
 translation unit and dynamically initialized shall be initialized in the
 order in which their definition appears
 in the translation unit.
 -------------------
 
 It seems clear to me that A::p1 cannot be statically initialized, and thus
 must follow the order of definition.
 
 Oliver, I think you are misreading the standard. If you de-legalise 14.7.1,
 it basically says that the compiler must generate code only for template
 (member) functions that are really used in the code. For completeness, it
 also says that static data members must be intialized only if they are
 really used, but it does not say in any way that initialization must be done
 WHEN the member is effectively used. In fact, all the initialization of
 static data members and non-local objects (like global static variables)
 must be done before main(), like §3.6.2 explains.
 
 Nathan, I agree that the order of instantiation is implementation defined,
 but the initialization of the static data members should happen before any
 template is instantiated. §14.7.1p8 decouples initialization of static data
 members and instantiation of class templates, saying that <<implicit
 instantiation of a class template does not cause any static data members of
 that class to be implicitly instantiated>>. In fact, <<static data members
 are initialized [...] exactly like nonlocal objects>> (§9.4.2p7), <<before
 any other initialization takes place>> (§3.6.2p1) (and of course only if
 <<the static data member is itself used in a way that requires the
 definition of the static data member to exist>> (§14.7.1p1).
 
 In the end, I believe that this is a bug in GCC, and other compilers (VC
 7.1, Comeau 4.3.0) seem to agree.
 
 Giovanni Bajo
 


------- Comment #7 From Gabriel Dos Reis 2003-03-18 02:46 -------
From: Gabriel Dos Reis <gdr@integrable-solutions.net>
To: "Giovanni Bajo" <giovannibajo@libero.it>
Cc: "Wolfgang Bangerth" <bangerth@ticam.utexas.edu>, <gcc-gnats@gcc.gnu.org>,
   <gcc-bugs@gcc.gnu.org>, <o.kullmann@swansea.ac.uk>, <nathan@gcc.gnu.org>
Subject: Re: c++/10112: static data member is not correctly initialized
Date: 18 Mar 2003 02:46:40 +0100

 "Giovanni Bajo" <giovannibajo@libero.it> writes:
 
 [...]
 
 | Nathan, I agree that the order of instantiation is implementation defined,
 | but the initialization of the static data members should happen before any
 | template is instantiated.
 
 From which parts of the standard did read that?
 
 | =A714.7.1p8 decouples initialization of static data
 | members and instantiation of class templates, saying that <<implicit
 | instantiation of a class template does not cause any static data members =
 of
 | that class to be implicitly instantiated>>. In fact, <<static data members
 | are initialized [...] exactly like nonlocal objects>> (=A79.4.2p7), <<bef=
 ore
 | any other initialization takes place>> (=A73.6.2p1) (and of course only if
 | <<the static data member is itself used in a way that requires the
 | definition of the static data member to exist>> (=A714.7.1p1).
 
 I can't read that to imply the your first assertion quoted above.
 
 -- Gaby


------- Comment #8 From Giovanni Bajo 2003-03-18 03:01 -------
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: "Gabriel Dos Reis" <gdr@integrable-solutions.net>
Cc: "Wolfgang Bangerth" <bangerth@ticam.utexas.edu>,
	<gcc-gnats@gcc.gnu.org>,
	<gcc-bugs@gcc.gnu.org>,
	<o.kullmann@swansea.ac.uk>,
	<nathan@gcc.gnu.org>
Subject: Re: c++/10112: static data member is not correctly initialized
Date: Tue, 18 Mar 2003 03:01:11 +0100

 ----- Original Message -----
 From: "Gabriel Dos Reis" <gdr@integrable-solutions.net>
 To: "Giovanni Bajo" <giovannibajo@libero.it>
 Cc: "Wolfgang Bangerth" <bangerth@ticam.utexas.edu>;
 <gcc-gnats@gcc.gnu.org>; <gcc-bugs@gcc.gnu.org>; <o.kullmann@swansea.ac.uk>;
 <nathan@gcc.gnu.org>
 Sent: Tuesday, March 18, 2003 2:46 AM
 Subject: Re: c++/10112: static data member is not correctly initialized
 
 
 >From which parts of the standard did read that?
 
 I was reading §3.6.2p1 <<before any other initialization takes place>> in
 this way.
 Anyway, the bug is about the order of initialization between two static data
 members. Since instantiation of class templates does not affect
 initialization of static data members (as per quoted paragraph), even if you
 instantiate the class templates before inizializing the data members, you
 should respect the order of inizialization of the data members.
 It seems to me that GCC is initializing the static data members because the
 templates are instantiated, but this violates §14.7.1p8.
 
 Giovanni Bajo
 


------- Comment #9 From Gabriel Dos Reis 2003-03-18 03:34 -------
From: Gabriel Dos Reis <gdr@integrable-solutions.net>
To: "Giovanni Bajo" <giovannibajo@libero.it>
Cc: "Wolfgang Bangerth" <bangerth@ticam.utexas.edu>, <gcc-gnats@gcc.gnu.org>,
   <gcc-bugs@gcc.gnu.org>, <o.kullmann@swansea.ac.uk>, <nathan@gcc.gnu.org>
Subject: Re: c++/10112: static data member is not correctly initialized
Date: 18 Mar 2003 03:34:23 +0100

 "Giovanni Bajo" <giovannibajo@libero.it> writes:
 
 | ----- Original Message -----
 | From: "Gabriel Dos Reis" <gdr@integrable-solutions.net>
 | To: "Giovanni Bajo" <giovannibajo@libero.it>
 | Cc: "Wolfgang Bangerth" <bangerth@ticam.utexas.edu>;
 | <gcc-gnats@gcc.gnu.org>; <gcc-bugs@gcc.gnu.org>; <o.kullmann@swansea.ac.u=
 k>;
 | <nathan@gcc.gnu.org>
 | Sent: Tuesday, March 18, 2003 2:46 AM
 | Subject: Re: c++/10112: static data member is not correctly initialized
 |=20
 |=20
 | >From which parts of the standard did read that?
 |=20
 | I was reading =A73.6.2p1 <<before any other initialization takes place>> =
 in
 | this way.
 
 That paragraph speaks about initialisation of objects.  It says
 nothing about the order of template instantiations and the order
 
 
 | Anyway, the bug is about the order of initialization between two static d=
 ata
 | members. Since instantiation of class templates does not affect
 | initialization of static data members (as per quoted paragraph), even if =
 you
 | instantiate the class templates before inizializing the data members, you
 | should respect the order of inizialization of the data members.
 
 Unless the instantiation of the class template uses the static data
 members.=20
 
 | It seems to me that GCC is initializing the static data members because t=
 he
 | templates are instantiated, but this violates =A714.7.1p8.
 
 What you're missing is  that your expression in the assertion
 introduces an indeterminism in the order of instantiation.  It is the
 instantiation of the static data members that defines them, not just
 their mere -template- definition.
 
 What is happening is not far from the following scenario:=20
 
    struct A {=20
       int p;
 =20
       A(int x) : p(x) { }
    };=20
 
    struct B {
       static A a;
       static int p1;
    };
 
     int B::p1 =3D a.p;
     A B::a(123);
 
   int main()
   {
     assert (B::a.p =3D=3D B::p1);
   }=20
 
 -- Gaby

------- Comment #10 From Andrew Pinski 2003-08-01 20:24 -------
*** Bug 11733 has been marked as a duplicate of this bug. ***

------- Comment #11 From Andrew Pinski 2004-01-29 04:16 -------
*** Bug 13915 has been marked as a duplicate of this bug. ***

------- Comment #12 From Andrew Pinski 2004-02-10 23:43 -------
*** Bug 14102 has been marked as a duplicate of this bug. ***

------- Comment #13 From Andrew Pinski 2004-10-09 14:36 -------
*** Bug 17910 has been marked as a duplicate of this bug. ***

------- Comment #14 From Wolfgang Bangerth 2004-10-09 18:09 -------
This PR has a long and wicked history. Presumably, PR 17910 is a duplicate 
so if anyone considers fixing this PR, she may as well go there first as 
PR 17910 has a very nice and small testcase. 
 
W. 

------- Comment #15 From Andrew Pinski 2004-10-14 14:33 -------
*** Bug 17910 has been marked as a duplicate of this bug. ***

------- Comment #16 From Jason Merrill 2009-11-08 23:27 -------
It's not clear to me that there's anything to be fixed; the reduced testcase in
this PR works, and the testcase for 17910 seems to work the way the point of
instantiation rules say it ought to.  And people can always use explicit
instantiation directives to control order of initialization.

Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug