[Bug c++/63526] New: O1 O2 O3 optimization and inline template constructor - uninitialized member

2014-10-13 Thread eles.david.88 at gmail dot com
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

2014-10-13 Thread eles.david.88 at gmail dot com
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

2014-10-13 Thread eles.david.88 at gmail dot com
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.