[Bug c++/63526] New: O1 O2 O3 optimization and inline template constructor - uninitialized member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63526 Bug ID: 63526 Summary: O1 O2 O3 optimization and inline template constructor - uninitialized member Product: gcc Version: unknown Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: eles.david.88 at gmail dot com Created attachment 33701 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33701&action=edit Test case It seems due to missing zero-initialization in case of inline constructor, I got a warning for uninitialized value for the following code: - main.cpp #include template struct Foo { Foo() {} void foo() {std::cout << _foo << std::endl;} T _foo; }; int main() { Foo f; f.foo(); return 0; } Compilation with "g++ -Wall", the result: everything is ok. Compilation with "g++ -Wall -O1", the result: main.cpp: In function ‘int main()’: main.cpp:10:4: warning: ‘f.Foo::_foo’ is used uninitialized in this function [-Wuninitialized] main.cpp:16:15: note: ‘f’ was declared here I got a same result with -O2, -O3. If the constructor is not inline, everything is ok. It seems that due to optimization the constructor "is inlined", but not in a prepare way, it "is inlined" without zero-initialization. Environment information: -- $uname -a Linux debian 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 GNU/Linux $g++ --version g++ (Debian 4.7.2-5) 4.7.2 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. --- A same behavior can be observed in older releases and distributions: --- $uname -a Linux rdv 2.6.18-164.6.1.el5 #1 SMP Tue Oct 27 11:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux $g++ --version g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. --- But not in the version: --- $g++ --version g++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-4) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ---
[Bug c++/63526] O1 O2 O3 optimization and inline template constructor - uninitialized member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63526 --- Comment #2 from Dávid Éles --- (In reply to Jonathan Wakely from comment #1) > Why do you think the member should be zero-initialized? Your constructor > fails to initialize it. I uses the default mechanism to initialization of members. As far as I know the C++ standard says (8.5/5): To default-initialize an object of type T means: * If T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor). * If T is an array type, each element is default-initialized. * Otherwise, the object is zero-initialized. In case of c++ it should be zero initialized if it is the member of a class/struct. As far as I know I have to force to not doing zero initialization something like that Foo* f = new Foo;
[Bug c++/63526] O1 O2 O3 optimization and inline template constructor - uninitialized member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63526 --- Comment #5 from Dávid Éles --- (In reply to Daniel Krügler from comment #3) > (In reply to Dávid Éles from comment #2) > > I uses the default mechanism to initialization of members. > > As far as I know the C++ standard says (8.5/5): > > To default-initialize an object of type T means: > > * If T is a non-POD class type (clause 9), the default constructor for T is > > called (and the initialization is ill-formed if T has no accessible default > > constructor). > > [Based on your quotes and your compiler settings you seem to quote the > C++98/03 standard. This is where my response is referred to as well] > > In your example an object of type Foo is default-initialized. Class > Foo is a non-POD class type, and therefore exactly this bullet is > entered. The result is what the wording says: the default constructor for T > (that is Foo in this example is called. The semantics of calling the > default-constructor of a class that has no member-initializer provided (such > as in this case) is specified in [class.base.init] p5: > > "If a given nonstatic data member or base class is not named by a > mem-initializer-id (including the case where there is no > mem-initializer-list because the constructor has no ctor-initializer), then > — If the entity is a nonstatic data member of (possibly cv-qualified) class > type (or array thereof) or a base class, and the entity class is a non-POD > class [..] > — Otherwise, the entity is not initialized. [..] > > The first bullet here does not apply, because the member is of type double > and thus does not match a class type. The second bullet therefore > unconditionally applied and says that the member is not initialized at all. > > > * If T is an array type, each element is default-initialized. > > This bullet does not apply > > > * Otherwise, the object is zero-initialized. > > This bullet does not apply. > > > In case of c++ it should be zero initialized if it is the member of a > > class/struct. > > No, you are incorrectly interpreting the Standard. > > > As far as I know I have to force to not doing zero initialization something > > like that Foo* f = new Foo; > > That has essentially the same initialization semantics as your example code. You are right, I missed it, thanks for your quick answer. Sorry to waste your time.