Bug 52477 - Wrong initialization order? __attribute__((constructor)) vs static data access
Summary: Wrong initialization order? __attribute__((constructor)) vs static data access
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.0
: P3 major
Target Milestone: ---
Assignee: Martin Liška
: 81337 (view as bug list)
Depends on:
Reported: 2012-03-04 12:50 UTC by Przemysław Pawełczyk
Modified: 2018-02-13 08:24 UTC (History)
6 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2017-03-16 00:00:00

Short exemplary code showing the problem (934 bytes, text/x-c++src)
2012-03-04 12:50 UTC, Przemysław Pawełczyk

Note You need to log in before you can comment on or make changes to this bug.
Description Przemysław Pawełczyk 2012-03-04 12:50:09 UTC
Created attachment 26821 [details]
Short exemplary code showing the problem

Attached file compiles flawlessly on 4.7.0, but the output binary segfaults. Works fine in 4.6.2 though (as expected).

Looks like a serious regression.

g++-4.7 (GCC) 4.7.0 20120304 (prerelease)
built on debian wheezy x64 with:
--enable-languages=c,c++ --prefix=/opt/gcc-4.7 --program-suffix=-4.7

Comment 1 Pawel Sikora 2012-03-04 13:54:09 UTC
looks like .init_array vs. .ctors problem.
Comment 2 Pawel Sikora 2012-03-04 14:16:29 UTC
you should specify explicit initialization order to avoid gpf, e.g.:

static std::map<int, int> m __attribute__((init_priority(101)));
static void insert() __attribute__((constructor(102)));
Comment 3 Przemysław Pawełczyk 2012-03-04 14:24:10 UTC
Thanks for solution, but...

Isn't such order obvious or isn't it at least the most widely used one? I mean that by default static data initialization should precede constructor-functions, no? It worked in gcc 4.6 and is there any good reason to break it?
Comment 4 Richard Biener 2012-03-05 10:20:37 UTC
I think it's undefined what you relied upon.
Comment 5 Martin Sebor 2017-03-15 23:00:48 UTC
Resolving as invalid based on comment #3.  The manual does seem to suggest that this should work:

   "The priorities for constructor and destructor functions are the same as those specified for namespace-scope C++ objects (see C++ Attributes)."

Let me add a blurb to make clear that the order between C++ ctors and functions declared attribute constructor is unspecified.

Blurb posted for review:
Comment 6 Jason Merrill 2017-03-16 04:46:52 UTC
I don't think this is undefined; it seems natural for these functions to be ordered with a translation unit along with dynamic initialization of non-local variables.  So for

extern "C" int printf (const char *, ...);

struct A { A() { printf ("A\n"); } } a;

static void B() __attribute__((constructor));
static void B()
  printf ("B\n");

struct C { C() { printf ("C\n"); } } c;

int main() {}

I would expect A B C, and gcc currently outputs B A C.  Instead of emitting constructor functions directly into .init_array as we do now, we should remember them and call them from __static_initialization_and_destruction_0.

Note that 4.6 gave the differently wrong A C B, due to running .init_array in the opposite order, so this isn't really a regression.
Comment 7 Martin Sebor 2017-03-20 18:34:03 UTC
Author: msebor
Date: Mon Mar 20 18:33:31 2017
New Revision: 246288

URL: https://gcc.gnu.org/viewcvs?rev=246288&root=gcc&view=rev
PR c++/52477 - Wrong initialization order __attribute__((constructor)) vs static data access

* doc/extend.texi (attribute constructor): Document present limitation.

Comment 8 Martin Sebor 2017-03-20 18:35:47 UTC
r246288 updates the manual for GCC 7 and documents the limitation (as per commetn #6) but the issue itself remains unresolved.
Comment 9 Martin Liška 2017-08-10 19:12:49 UTC
*** Bug 81337 has been marked as a duplicate of this bug. ***
Comment 10 Martin Liška 2017-08-10 19:13:38 UTC
I will try to look at it.
Comment 11 Rainer Orth 2018-02-01 10:24:49 UTC
(In reply to Martin Liška from comment #10)
> I will try to look at it.

Do you see a chance to look at this before GCC 8?

Comment 12 Martin Liška 2018-02-13 08:24:48 UTC
(In reply to Rainer Orth from comment #11)
> (In reply to Martin Liška from comment #10)
> > I will try to look at it.
> Do you see a chance to look at this before GCC 8?
> Thanks.
>   Rainer

I'm sorry but probably after the release in next stage1.