This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: c++/10112: static data member is not correctly initialised
- From: "Giovanni Bajo" <giovannibajo at libero dot it>
- To: <gcc-gnats at gcc dot gnu dot org>,<gcc-bugs at gcc dot gnu dot org>,<nobody at gcc dot gnu dot org>,<O dot Kullmann at Swansea dot ac dot uk>,<gcc-prs at gcc dot gnu dot org>
- Date: Sun, 16 Mar 2003 23:22:30 +0100
- Subject: Re: c++/10112: static data member is not correctly initialised
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