Topic: implicitly declared default constructor isn't generated


Author: Jason Merrill <jason@cygnus.com>
Date: 1996/01/04
Raw View
[ Moderator's note: this thread originated from gnu.g++.bug. ]
[ To fill you in on the missing context, the question at hand   ]
[ is whether or not the code fragment    ]
[        ]
[ struct Int {      ]
[  Int( int x ) : x( x ) {}   ]
[  int x;      ]
[ };       ]
[        ]
[ int main() {      ]
[  Int* pi( new Int[ 2 ] );   ]
[  delete pi;     ]
[  return 0;     ]
[ }       ]
[        ]
[ is well-formed. -fjh.     ]

>>>>> Rohan LENARD <rjl@iassf.easams.com.au> writes:

> This looks like a hang-over from the ARM, which explicitely stated that
> array of objects will be created by calling all the default ctors.  The
> April draft working paper seems to allow this -

> #include <stdio.h>

> struct Int
>           {
>               Int( int x ) : x( x ) {
>    fprintf(stderr,"X = %d\n",x);
>   }
>               int x;
>           };
>           int
>           main()
>           {
>               Int* pi = new Int[ 2 ](3); // Initialise all elements with
> ctor called with (3).
>               delete pi;
>               return 0;
>           }

Nope; that does not fall into any of the well-formed cases, since Int[2] is
not a class type.

>> Quite right, I read the draft working paper too quickly.  From my
>> point of view though, it should still compile.  According to section
>> 5.3.4 [expr.new] verse 14, the object created by the expression `new
>> Int[ 2 ]' has indeterminate value, which I took to mean the default
>> constructor isn't called, while `new Int[ 2 ]()' does invoke the
>> default constructor.  Is that not a reasonable interpretation?

Nope; Int[2] is an array of non-POD class type, so it falls under item 1
of 5.3.4p14.

>> Here's the code snippet again:

>> struct Int
>> {
>> Int( int x ) : x( x ) {}
>> int x;
>> };

>> int
>> main()
>> {
>> Int* pi( new Int[ 2 ] );
>> delete pi;

>> return 0;
>> }

14If the type of the object created by the new-expression is T:

  --If  the  new-initializer  is  omitted  and T is a non-POD class type
    (_class_) (or array thereof), then if the default constructor for  T
    is accessible it is called, otherwise the program is ill-formed;

  --If   the   new-initializer   is   omitted   and  T  is  a  POD  type
    (_basic.types_), then the  object  thus  created  has  indeterminate
    value;

  --If  the  new-initializer  is  of the form (), default-initialization
    shall be performed (_dcl.init_);

  --If the new-initializer is of the form expression-list) and  T  is  a
    class type, the appropriate constructor is called, using expression-
    list as the arguments (_dcl.init_);

  --If the new-initializer is of the form expression-list) and T  is  an
    arithmetic,  enumeration,  pointer,  or  pointer-to-member  type and
    expression-list comprises exactly one expression, then the object is
    initialized  to  the  (possibly  converted)  value of the expression
    (_dcl.init_);

  --Otherwise the new-expression is ill-formed.
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: ebiederm@cse.unl.edu (Eric W. Biederman)
Date: 1996/01/06
Raw View
In article <fjh-960105-011629@cs.mu.oz.au> Jason Merrill <jason@cygnus.com> wri
tes:

   [ Moderator's note: this thread originated from gnu.g++.bug. ]
   [ To fill you in on the missing context, the question at hand]
   [ is whether or not the code fragment   ]
   [        ]
   [ struct Int {      ]
   [  Int( int x ) : x( x ) {}   ]
   [  int x;      ]
   [ };       ]
   [        ]
   [ int main() {      ]
   [  Int* pi( new Int[ 2 ] );   ]
   [  delete pi;     ]
   [  return 0;     ]
   [ }       ]
   [        ]
   [ is well-formed. -fjh.     ]

Well to answer the superficial question here the code is wrong.

It should read
   delete [] pi;
not
   delete pi;


Eric
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/01/06
Raw View
ebiederm@cse.unl.edu (Eric W. Biederman) writes:

>   [ Moderator's note: this thread originated from gnu.g++.bug.]
>   [ To fill you in on the missing context, the question at hand]
>   [ is whether or not the code fragment   ]
>   [        ]
>   [ struct Int {      ]
>   [  Int( int x ) : x( x ) {}   ]
>   [  int x;      ]
>   [ };       ]
>   [        ]
>   [ int main() {      ]
>   [  Int* pi( new Int[ 2 ] );   ]
>   [  delete pi;     ]
>   [  return 0;     ]
>   [ }       ]
>   [        ]
>   [ is well-formed. -fjh.     ]
>
>Well to answer the superficial question here the code is wrong.
>
>It should read
>   delete [] pi;
>not
>   delete pi;

The code is definitely wrong - but the above mistake with delete would
"only" cause undefined behaviour, it would not mean that the program
was not ``well-formed'', which is a technical term defined in the draft
standard:

|  --well-formed program: a C++ program constructed according to the syn-
|    tax rules, diagnosable semantic rules, and the One  Definition  Rule
|    (_basic.def_).

As it turns out, the code is indeed ill-formed (not well-formed) because it
violates a diagnosable semantic rule, as discussed earlier in this thread.

--
Fergus Henderson              WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au               PGP: finger fjh@128.250.37.3
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]