Compile this code and see that __static_initialization_and_destruction_0 exists and but it should produce static initializers: class Fred { public: Fred(int x) : x_(x) { } private: int x_; }; class Barney : public Fred { public: Barney(int x, int y) : Fred(x), y_(y) { } private: int y_; }; extern const Barney abarney(5, 6); extern const Fred afred(2);
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 unit. But as I said, some language lawyer will tell whether this optimization can be done or not. W.
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.
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. W.
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 copy_rtx_if_shared.
Taking the fact that the tree-ssa already optimizes the code better than the mainline, I am closing this bug as will not fix.
FWIW, llvm-g++ gets this right.
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
Dup. *** This bug has been marked as a duplicate of bug 4131 ***