Subject: g++-3.3: default construction fails when no explicit default constructor defined

From: Herbert Valerio Riedel <[email-masked]>
Date: Fri, 30 May 2003 21:26:32 +0200

Package: g++-3.3
Version: 1:3.3-2
Severity: normal

I'm not sure, whether this should work according to the ISO C++ specs or
not; IMHO it should work... :-)

$ cat static_var.cc

class bar {
public:
  int operator()(int i) { return i; }
  //bar (void) {} // default constructor
};

const bar b = bar (); // works always...
const bar b2; // fails if there is no explicit default constructor
$ g++ -c -O0 -Wall static_var.cc
static_var.cc:9: uninitialized const `b2'
$

if the commented out default constructor is enabled, compilation
succeeds...

-- System Information:
Debian Release: testing/unstable
Architecture: i386
Kernel: Linux lfdux.ifs.tuwien.ac.at 2.4.20-1-k7 #1 Sat Mar 22 15:17:52 EST 2003 i686
Locale: LANG=C, LC_CTYPE=C

Versions of packages g++-3.3 depends on:
ii  gcc-3.3                       1:3.3-2    The GNU C compiler
ii  gcc-3.3-base                  1:3.3-2    The GNU Compiler Collection (base 
ii  libc6                         2.3.1-17   GNU C Library: Shared libraries an
ii  libstdc++5-3.3-dev            1:3.3-2    The GNU Standard C++ Library v3 (d

-- no debconf information

---

From: Phil Edwards <[email-masked]>
Date: Fri, 30 May 2003 16:08:29 -0400

> if the commented out default constructor is enabled, compilation

Or if you declare b2 as non-const.  This is not a bug.

-- 
If ye love wealth greater than liberty, the tranquility of servitude greater
than the animating contest for freedom, go home and leave us in peace.  We seek
not your counsel, nor your arms.  Crouch down and lick the hand that feeds you;
and may posterity forget that ye were our countrymen.            - Samuel Adams

---

From: Herbert Valerio Riedel <[email-masked]>
Date: 31 May 2003 02:00:28 +0200

> Or if you declare b2 as non-const.  This is not a bug.

I've reconsidered the problem;

now to me it looks, as if g++ behaves as if bar was a POD type (actually
the class defined above seems to qualify as POD type) since for those
cases, "const bar b2;" would really be uninitialized, since:

>A non-const POD object declared with no initializer has an
>"indeterminate initial value" [§8.5, ¶9].

thus compiling "const <POD-type> foo;" is sensible to fail...
but on the other hand, what 'indeterminate initial value' can there be,
if the struct doesn't contain any data member at all?!?
(fyi, 3 other c++ compilers I've tried compiled the code above
successfully...)

but, according to http://home.fnal.gov/~wb/POD.html, the following would
definitely not be a POD type:

class bar {}; // base class

class foo: public bar { // foo has a base class...
  int m_int; // "protected non-static data member"
protected:
  int m_int2; // "protected non-static data member"
public:
  foo operator=(const foo &f) { return *this; } // "user-defined copy
//assignment operator"
  ~foo () {} // "user-defined destructor"
};

const foo b; // "error: uninitialized const `b'"

...and yet g++-3.[23] fails to compile this... 

(btw...if I'd add a virtual function, or a user declared default
constructor, or some non-POD non-static data member, then the code would
compile...)

...so... is _still_ not a buggy behaviour??

regards,
-- 
Herbert Valerio Riedel       /    Phone: (EUROPE) +43-1-58801-18840
Email: [email-masked]       /    Finger [email-masked] for GnuPG Public Key
GnuPG Key Fingerprint: 7BB9 2D6C D485 CE64 4748  5F65 4981 E064 883F 4142

---

From: [email-masked] (Martin v. Löwis)
Date: 31 May 2003 10:35:27 +0200

> ...so... is _still_ not a buggy behaviour??

No. Look at 8.5/9:

# If no initializer is specified for an object, and the object is of
# (possibly cv-qualified) non-POD class type (or array thereof), the
# object shall be default-initialized; if the object is of
# const-qualified type, the underlying class type shall have a
# user-declared default constructor.

Your objects have const-qualified type, and the underlying class has
no user-declared default constructor, hence your program is
ill-formed. 

Whether there would be any members with indeterminate state is
irrelevant, as is the fact that three other compilers fail to find
that ill-formedness.

Regards,
Martin

---

From: Herbert Valerio Riedel <[email-masked]>
Date: 31 May 2003 11:43:14 +0200

> # user-declared default constructor.
[..]
# Otherwise, if no initializer is specified for anobject, the object 
# and its subobjects, if any, have an indeterminate initial value; if
# the object or any of its subobjects are of const-qualified type, the
# program is ill-formed.

> no user-declared default constructor, hence your program is

alright, then g++'s fault is to fail to recognize the ill-formed-ness of
at least the following cases, happily succeeds compiling them...:

struct foo {
  virtual void f(void);
};

struct bar {
  bar (); // user defined default constructor
};

struct doo {
  bar m_bar; // non-POD member w/ u.d.d.c
};

struct zoo: public bar { }; // inherited u.d.d.c

const foo a_foo; // ill-formed - foo has no user-declared def-cons
const bar a_bar; // ok
const doo a_doo; // ill-formed - doo has no user-declared def-cons
const zoo a_zoo; // ill-formed? not sure about this one...

reagards,