Bug 11211 - trivial static initializers of const objects should be done at compile time
Summary: trivial static initializers of const objects should be done at compile time
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: missed-optimization
Depends on:
Reported: 2003-06-16 16:43 UTC by Andrew Pinski
Modified: 2008-12-28 11:21 UTC (History)
2 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Pinski 2003-06-16 16:43:00 UTC
Compile this code and see that __static_initialization_and_destruction_0 exists and but it should 
produce static initializers:
class Fred {
      Fred(int x) : x_(x) { }

      int x_;

class Barney : public Fred {
      Barney(int x, int y) : Fred(x), y_(y) { }

      int y_;

extern const Barney abarney(5, 6);
extern const Fred afred(2);
Comment 1 Wolfgang Bangerth 2003-06-16 19:06:43 UTC
IIRC, the standard prescribes that these objects be placed in a memory
location that is originally zero-initialized, and only set when the
constructor is run. So the behavior is correct, but I'd like to
hear from a language lawyer. (There is a related PR somewhere we this
was discussed in great detail -- ah, PR 9881. And PR 4131 may also
be related.)

The question then is: is there a program which can detect the difference?
I think in this case, you can: the variable is declared externally visible,
so constructors of other variables running in a different translation
unit before the constructors of this unit may access the memory of this

But as I said, some language lawyer will tell whether this optimization can
be done or not.

Comment 2 eric-gcc 2003-06-16 23:43:19 UTC
After reading those sections, I think the optimization could only be applied in
some limited, but possibly still useful circumstances.  The order in which
constructors are run for global variables is undefined between translation
units.  So, the optimization could only be applied when the definitions of afred
and abarney appeared before everything else in the translation unit.

The standard would have to say something about all the constructors from one
translation unit always being run either before, or after the constructors in
another translation unit, and I don't think it does.

Also, if the variables were static variables in a function, then you couldn't
apply the optimization, since the constructors for such variables aren't
supposed to be run until the funtion is called the first time.  Static,
function-scope variables shouldn't be subject to the suggested optimization.

Of course, I'm only a novice language lawyer, and don't have the exact text of
the standard sitting in front of me.
Comment 3 Wolfgang Bangerth 2003-06-17 13:46:21 UTC
JFYI, the standard indeed gives no provisions as to which constructors
from which translation unit are run first, but gcc can guarantee this
nevertheless on some systems using priority attributes on variables.

However, since nothing is known about which priorities are used in
other translation units, this is nothing we can use for optimization
here. I personally think that this proposed optimization would
apply to too few variables that it would be worth it. But that's just
my opinion.

Comment 4 Andrew Pinski 2003-07-19 02:44:20 UTC
One more interseting thing this would prevent is PR 10060 which is an ICE because of 
there are a large number of static initializers.  Right now the code in 
__static_initialization_and_destruction_0 is hugh which causes this ICE in 
Comment 5 Andrew Pinski 2003-11-18 07:12:57 UTC
Taking the fact that the tree-ssa already optimizes the code better than the mainline, I am closing 
this bug as will not fix.
Comment 6 Chris Lattner 2008-12-06 22:44:47 UTC
FWIW, llvm-g++ gets this right.
Comment 7 eric-bugs 2008-12-28 11:21:14 UTC
I've been meaning to revisit this bug with a recent version of gcc.  And, in fact it still happens with gcc 4.3.0