This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]