Topic: aggregates v. synthesized constructors


Author: jason@cygnus.com (Jason Merrill)
Date: Tue, 18 Jan 1994 20:15:13 GMT
Raw View
>>>>> Robin Albrecht <robina@wv.mentorg.com> writes:

> Okay.  My posting was intended to clear up what seemed to me to be the
> original poster's confusion in stating that because the ARM "does not
> mention when the constructor should be generated, only when it
> shouldn't...thus I assume it should always be."  (A case is given when it
> shouldn't be generated, so how could the intent be to mean that it should
> always be?)

I guess I was unclear.  When I said "always" I meant "whenever possible",
i.e. if and only if.

Jason




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sat, 15 Jan 1994 17:38:26 GMT
Raw View
jason@cygnus.com (Jason Merrill) writes:

>12.1: "A default constructor will be generated for a class X only if no
>constructor has been declared for class X."
>
>12.8: "If not declared by the programmer, [a copy constructor] will if
>possible be automatically definded (synthesized")..."
>
>8.4.1: "An aggregate is an array or an object of a class with no constructors"
>
>As I read 12.8, it seems to indicate that all classes should have either an
>X::X(const X&) or an X::X(X&) constructor.  12.1 also seems to imply that
>all classes should have an X::X() constructor, though it reads "only if"
>rather than "if and only if".

ARM 12.1 also states "Default constructors and copy constructors, however,
are generated (by the compiler) where needed (12.8)."
This is the "if" part to go with the above "only if".

>The way it is currently worded, it does not
>mention when the constructor should be generated, only when it shouldn't;
>thus I assume it should always be.

It should be generated whenever it is needed.

>But then 8.4.1 specifies that no class with constructors can be initialized
>with a bracketed initializer list.
>
>Thoughts?  Perhaps the copy and default constructors should not count in
>this and similar situations.  Perhaps only synthesized constructors should
>not count.

The latter.  The ARM in general is a bit confusing (confused?) about
this issue.  When it talks about classes without constructors it should
really be talking about classes without any user-defined constructors.
Constructors that are generated by the compiler don't count for this
purpose.

--
Fergus Henderson        |   "People who brook no compromise in programming
                        |   languages should program in lambda calculus or
fjh@munta.cs.mu.OZ.AU   |   machine language, depending." --Andrew Koenig.




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sat, 15 Jan 1994 06:45:56 GMT
Raw View
In article <1994Jan14.032713.14707@news.mentorg.com> robina@wv.mentorg.com (Robin Albrecht) writes:
>In article <JASON.94Jan13150703@deneb.cygnus.com>, jason@cygnus.com (Jason Merrill) writes:
>|> 12.1:
>|>
>|> "A default constructor will be generated for a class X only if no
>|> constructor has been declared for class X."
>|>
>|> 12.8:
>|>
>|> "A class object can be copied in two ways, by assignment and by
>|> initialization . . . .  Conceptually, for a class X these two operations
>|> are implemented by an assignment operator and a copy constructor.  If not
>|> declared by the programmer, they will if possible be automatically definded
>|> (synthesized") . . . .
>|>
>|> 8.4.1:
>|>
>|> "An aggregate is an array or an object of a class with no constructors . .
>|> . ."
>|>
>|>
>|> As I read 12.8, it seems to indicate that all classes should have either an
>|> X::X(const X&) or an X::X(X&) constructor.  12.1 also seems to imply that
>|> all classes should have an X::X() constructor, though it reads "only if"
>|> rather than "if and only if".  The way it is currently worded, it does not
>|> mention when the constructor should be generated, only when it shouldn't;
>|> thus I assume it should always be.
>
>That's a bad assumption in this case.  Unless doing exercises for a class
>in logic (which, admittedly, this newsgroup comes very close to), or dealing
>with the very rigid (which, admittedly, happens often here), "only if" means
>"if and only if".  That is the way it is understood by the community in this
>case, anyway.

 That is NOT THE CASE. Bjarne was very careful to use
correct logic. A class containing a reference cannot have ANY
constructors or assignment operator generated by the compiler.

 ONLY IF is correct, IF AND ONLY IF is wrong.


 The original post correctly points out a weakness in
the ARM specifications. Its not clear exactly what

 "has no constructors"

means. Its clear that most classes -- including most aggregates --
actually do have copy constructors. 12.1 should read:

 "has no user defined constructors".

I believe.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sun, 16 Jan 1994 12:04:08 GMT
Raw View
In article <9401604.3634@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>The latter.  The ARM in general is a bit confusing (confused?) about
>this issue.  When it talks about classes without constructors it should
>really be talking about classes without any user-defined constructors.
>Constructors that are generated by the compiler don't count for this
>purpose.

 Dont be so sure. There is a distinction between a class
with NO constructors and one with no USER defined constructors
and one with TRIVIAL constructors (which are always compiler generated).
It took me a while to figure this out, but the distinction is
important.

 struct A { string x; }; // no USER defined constructors
 struct B { string x; int& y; }; // NO CONSTRUCTORS

 struct C { int a; int b; };  // TRIVIAL constructors
 // trivial default constructor bitwise copy and assignment
 // trivial destructor

As far as I know, all three of these classes are aggregates.
However, A and B may not partake in a union.
(I dont know how B manages to be an aggregate)

On the other hand

 class D { int a; friend class E;};

isnt an aggregate.


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: robina@wv.mentorg.com (Robin Albrecht)
Date: Mon, 17 Jan 1994 22:31:28 GMT
Raw View
In article <CJns4K.E3M@ucc.su.OZ.AU>, maxtal@physics.su.OZ.AU (John Max Skaller) writes:
|> In article <1994Jan14.032713.14707@news.mentorg.com> robina@wv.mentorg.com (Robin Albrecht) writes:
|> >In article <JASON.94Jan13150703@deneb.cygnus.com>, jason@cygnus.com (Jason Merrill) writes:
|> >|> 12.1:
|> >|>
|> >|> "A default constructor will be generated for a class X only if no
|> >|> constructor has been declared for class X."
|> >|>
|> >|> 12.8:
|> >|>
|> >|> "A class object can be copied in two ways, by assignment and by
|> >|> initialization . . . .  Conceptually, for a class X these two operations
|> >|> are implemented by an assignment operator and a copy constructor.  If not
|> >|> declared by the programmer, they will if possible be automatically definded
|> >|> (synthesized") . . . .
|> >|>
|> >|> 8.4.1:
|> >|>
|> >|> "An aggregate is an array or an object of a class with no constructors . .
|> >|> . ."
|> >|>
|> >|>
|> >|> As I read 12.8, it seems to indicate that all classes should have either an
|> >|> X::X(const X&) or an X::X(X&) constructor.  12.1 also seems to imply that
|> >|> all classes should have an X::X() constructor, though it reads "only if"
|> >|> rather than "if and only if".  The way it is currently worded, it does not
|> >|> mention when the constructor should be generated, only when it shouldn't;
|> >|> thus I assume it should always be.
|> >
|> >That's a bad assumption in this case.  Unless doing exercises for a class
|> >in logic (which, admittedly, this newsgroup comes very close to), or dealing
|> >with the very rigid (which, admittedly, happens often here), "only if" means
|> >"if and only if".  That is the way it is understood by the community in this
|> >case, anyway.
|>
|>  That is NOT THE CASE. Bjarne was very careful to use
|> correct logic. A class containing a reference cannot have ANY
|> constructors or assignment operator generated by the compiler.
|>
|>  ONLY IF is correct, IF AND ONLY IF is wrong.

Okay.  My posting was intended to clear up what seemed to me to be the
original poster's confusion in stating that because the ARM "does not mention
when the constructor should be generated, only when it shouldn't...thus I
assume it should always be."  (A case is given when it shouldn't be
generated, so how could the intent be to mean that it should always be?)

|>
|>
|>  The original post correctly points out a weakness in
|> the ARM specifications. Its not clear exactly what
|>
|>  "has no constructors"
|>
|> means. Its clear that most classes -- including most aggregates --
|> actually do have copy constructors. 12.1 should read:
|>
|>  "has no user defined constructors".
|>
|> I believe.
|>
|> --
|>         JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
|>  Maxtal Pty Ltd,      CSERVE:10236.1703
|>         6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
|>         NSW 2131, AUSTRALIA

--
Robin Albrecht
Mentor Graphics, IC Division
Email: robin_albrecht@mentorg.com




Author: jason@cygnus.com (Jason Merrill)
Date: Thu, 13 Jan 1994 23:07:03 GMT
Raw View
12.1:

"A default constructor will be generated for a class X only if no
constructor has been declared for class X."

12.8:

"A class object can be copied in two ways, by assignment and by
initialization . . . .  Conceptually, for a class X these two operations
are implemented by an assignment operator and a copy constructor.  If not
declared by the programmer, they will if possible be automatically definded
(synthesized") . . . .

8.4.1:

"An aggregate is an array or an object of a class with no constructors . .
. ."


As I read 12.8, it seems to indicate that all classes should have either an
X::X(const X&) or an X::X(X&) constructor.  12.1 also seems to imply that
all classes should have an X::X() constructor, though it reads "only if"
rather than "if and only if".  The way it is currently worded, it does not
mention when the constructor should be generated, only when it shouldn't;
thus I assume it should always be.

But then 8.4.1 specifies that no class with constructors can be initialized
with a bracketed initializer list.

Thoughts?  Perhaps the copy and default constructors should not count in
this and similar situations.  Perhaps only synthesized constructors should
not count.

Jason




Author: robina@wv.mentorg.com (Robin Albrecht)
Date: Fri, 14 Jan 1994 03:27:13 GMT
Raw View
In article <JASON.94Jan13150703@deneb.cygnus.com>, jason@cygnus.com (Jason Merrill) writes:
|> 12.1:
|>
|> "A default constructor will be generated for a class X only if no
|> constructor has been declared for class X."
|>
|> 12.8:
|>
|> "A class object can be copied in two ways, by assignment and by
|> initialization . . . .  Conceptually, for a class X these two operations
|> are implemented by an assignment operator and a copy constructor.  If not
|> declared by the programmer, they will if possible be automatically definded
|> (synthesized") . . . .
|>
|> 8.4.1:
|>
|> "An aggregate is an array or an object of a class with no constructors . .
|> . ."
|>
|>
|> As I read 12.8, it seems to indicate that all classes should have either an
|> X::X(const X&) or an X::X(X&) constructor.  12.1 also seems to imply that
|> all classes should have an X::X() constructor, though it reads "only if"
|> rather than "if and only if".  The way it is currently worded, it does not
|> mention when the constructor should be generated, only when it shouldn't;
|> thus I assume it should always be.

That's a bad assumption in this case.  Unless doing exercises for a class
in logic (which, admittedly, this newsgroup comes very close to), or dealing
with the very rigid (which, admittedly, happens often here), "only if" means
"if and only if".  That is the way it is understood by the community in this
case, anyway.

|>
|> But then 8.4.1 specifies that no class with constructors can be initialized
|> with a bracketed initializer list.
|>
|> Thoughts?  Perhaps the copy and default constructors should not count in
|> this and similar situations.  Perhaps only synthesized constructors should
|> not count.
|>
|> Jason

Regards,

Robin
--
Robin Albrecht
Mentor Graphics, IC Division
Email: robin_albrecht@mentorg.com