Topic: Q: is A a = 100; equivalent to A a (100); ?
Author: damian@molly.cs.monash.edu.au (Damian Conway)
Date: 1995/10/18 Raw View
kanze <kanze@lts.sel.alcatel.de> writes:
>In article <45sl3a$coc@engnews2.Eng.Sun.COM> clamage@Eng.sun.com
>(Steve Clamage) writes:
>|> damian@molly.cs.monash.edu.au (Damian Conway) writes:
>|> >Then is it possible to set up a class X wherein:
>|> > X x(1);
>|> >and
>|> > X x = 1;
>|> >behave differently?
>|> Yes. Silly example: Write a message to the terminal from the copy
>|> constructor. If the copy is optimized away, you won't see the message.
>I don't think that is what he was looking for. As far as I know,
>there is no way of *ensuring* that the above will both be legal, but
>have garanteed different run-time semantics.
Yes, that was what I was asking.
>It is trival to make the first legal, and the second illegal, which, I
>suppose is a way of making them behave differently at compile time.
:-)
BTW: What was the rationale for making something as fundamental as copy
initialization non-portable (in the sense that it has no guaranteed
semantics)?
damian
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~
who: Damian Conway email: damian@bruce.cs.monash.edu.au
where: Dept. Computer Science phone: +61-3-565-5184
Monash University fax: +61-3-565-5146
Clayton 3168 quote: "A pessimist is never disappointed.
"
AUSTRALIA
---
[ 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: b91926@fsgm01.fnal.gov (David Sachs)
Date: 1995/10/18 Raw View
damian@molly.cs.monash.edu.au (Damian Conway) writes:
>kanze <kanze@lts.sel.alcatel.de> writes:
>>In article <45sl3a$coc@engnews2.Eng.Sun.COM> clamage@Eng.sun.com
>>(Steve Clamage) writes:
>>|> damian@molly.cs.monash.edu.au (Damian Conway) writes:
>>|> >Then is it possible to set up a class X wherein:
>>|> > X x(1);
>>|> >and
>>|> > X x = 1;
>>|> >behave differently?
>>|> Yes. Silly example: Write a message to the terminal from the copy
>>|> constructor. If the copy is optimized away, you won't see the message.
>>I don't think that is what he was looking for. As far as I know,
>>there is no way of *ensuring* that the above will both be legal, but
>>have garanteed different run-time semantics.
>Yes, that was what I was asking.
>>It is trival to make the first legal, and the second illegal, which, I
>>suppose is a way of making them behave differently at compile time.
>:-)
>BTW: What was the rationale for making something as fundamental as copy
> initialization non-portable (in the sense that it has no guaranteed
> semantics)?
While it is not easy to write an example in which
X x(1); and X x = 1; are guaranteed to behave differently, it is quite
easy to produce a case in which X x(a); and X x=a; behave differently,
where a is a class object, of a class that has a conversion operator to
X&, and another higher priority conversion to something accepted by a
constructor of class X. then:
X x(a) uses higher priority conversion by overloading rules
X x=a uses X(a.operator X&)
At least this is the way I think it works.
--
** The Klingons' favorite food was named by the first earthling to see it **
David Sachs - Fermilab, HPPC MS369 - P. O. Box 500 - Batavia, IL 60510
Voice: 1 708 840 3942 Deparment Fax: 1 708 840 3785
---
[ 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: matt@godzilla.EECS.Berkeley.EDU (Matt Austern)
Date: 1995/10/18 Raw View
In article <4638jp$ef4@fsgm01.fnal.gov> b91926@fsgm01.fnal.gov (David Sachs) writes:
> X x(a) uses higher priority conversion by overloading rules
>
> X x=a uses X(a.operator X&)
Sort of. If a is of class A, if the copy constructor X::X(const X&)
exists, and if the converting constructor X::X(const A&) exists and
isn't qualified as explicit, then "X x(a)" simply invokes the
converting constructor while "X x=a" invokes the converting
constructor and then the copy constructor.
Section 12.6 of the working paper explains this in detail. The rest
of chapter 12 is somewhat relevant too.
--
Matt Austern He showed his lower teeth. "We
matt@physics.berkeley.edu all have flaws," he said, "and
http://dogbert.lbl.gov/~matt mine is being wicked."
---
[ 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: b91926@fsgm01.fnal.gov (David Sachs)
Date: 1995/10/19 Raw View
matt@godzilla.EECS.Berkeley.EDU (Matt Austern) writes:
>In article <4638jp$ef4@fsgm01.fnal.gov> b91926@fsgm01.fnal.gov (David Sachs) w
rites:
>> X x(a) uses higher priority conversion by overloading rules
>>
>> X x=a uses X(a.operator X&)
>Sort of. If a is of class A, if the copy constructor X::X(const X&)
>exists, and if the converting constructor X::X(const A&) exists and
>isn't qualified as explicit, then "X x(a)" simply invokes the
>converting constructor while "X x=a" invokes the converting
>constructor and then the copy constructor.
>Section 12.6 of the working paper explains this in detail. The rest
>of chapter 12 is somewhat relevant too.
If X had a constructor X(A&), there might be some ambiguity, but
suppose X has a constructor X(B&), where B is a unique base class of
A.
Then X x(a); means X X(B&(a)); as trying X(a.operator X&()) would use
a lower priority user conversion.
X x = a; should use the direct conversion function.
--
** The Klingons' favorite food was named by the first earthling to see it **
David Sachs - Fermilab, HPPC MS369 - P. O. Box 500 - Batavia, IL 60510
Voice: 1 708 840 3942 Deparment Fax: 1 708 840 3785
---
[ 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: Michael Cook <mcook@cognex.com>
Date: 1995/10/19 Raw View
>>>>> "SC" == Steve Clamage <clamage@Eng.sun.com> writes:
SC> Silly example: Write a message to the terminal from the copy
SC> constructor. If the copy is optimized away, you won't see the message.
If the constructor writes a message to the terminal, then the contructor has
side effects. Such a constructor could not be optimized away and still
conform to the (drafts) standard, right?
By adding "write" statements to your constructor, you affect the system you're
trying to observe, and then the laws of quantum mechanics kick in and cause
your progam to start emitting bogon particles. :-)
Michael.
---
[ 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: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/10/19 Raw View
Matt Austern (matt@godzilla.EECS.Berkeley.EDU) wrote:
|> In article <4638jp$ef4@fsgm01.fnal.gov> b91926@fsgm01.fnal.gov (David Sachs) writes:
|> > X x(a) uses higher priority conversion by overloading rules
|> >
|> > X x=a uses X(a.operator X&)
|> Sort of. If a is of class A, if the copy constructor X::X(const X&)
|> exists, and if the converting constructor X::X(const A&) exists and
|> isn't qualified as explicit, then "X x(a)" simply invokes the
|> converting constructor while "X x=a" invokes the converting
|> constructor and then the copy constructor.
Except that there is no guarantee that the copy constructor will
actually be invoked. The compiler is allowed to optimize it away.
|> Section 12.6 of the working paper explains this in detail. The rest
|> of chapter 12 is somewhat relevant too.
Concerning the original posting: I don't think it will work. As I
understand what you are suggesting:
class B {} ;
class D : public B { operator B() ; } ;
D aD ;
B aB( aD ) ;
B anotherB = aD ;
What you are saying is that in the first case, D::operator B() will not
be considered, and in the second case, it will be used.
In fact, in both cases, it will be considered, but as a user defined
conversion, it is pretty far down on the scale; in both cases, the
derived->base conversion will have precedence. (I believe.)
--
James Kanze (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
--Beratung in industrieller Datenverarbeitung
---
[ 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: b91926@fsgm01.fnal.gov (David Sachs)
Date: 1995/10/19 Raw View
kanze@gabi-soft.fr (J. Kanze) writes:
>Matt Austern (matt@godzilla.EECS.Berkeley.EDU) wrote:
>|> In article <4638jp$ef4@fsgm01.fnal.gov> b91926@fsgm01.fnal.gov (David Sachs) writes:
>|> > X x(a) uses higher priority conversion by overloading rules
>|> >
>|> > X x=a uses X(a.operator X&)
>|> Sort of. If a is of class A, if the copy constructor X::X(const X&)
>|> exists, and if the converting constructor X::X(const A&) exists and
>|> isn't qualified as explicit, then "X x(a)" simply invokes the
>|> converting constructor while "X x=a" invokes the converting
>|> constructor and then the copy constructor.
>Except that there is no guarantee that the copy constructor will
>actually be invoked. The compiler is allowed to optimize it away.
>|> Section 12.6 of the working paper explains this in detail. The rest
>|> of chapter 12 is somewhat relevant too.
>Concerning the original posting: I don't think it will work. As I
>understand what you are suggesting:
> class B {} ;
> class D : public B { operator B() ; } ;
> D aD ;
> B aB( aD ) ;
> B anotherB = aD ;
>What you are saying is that in the first case, D::operator B() will not
>be considered, and in the second case, it will be used.
>In fact, in both cases, it will be considered, but as a user defined
>conversion, it is pretty far down on the scale; in both cases, the
>derived->base conversion will have precedence. (I believe.)
> is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
I am relying on paragraph 2 of scetion 12.3.2 of the proposed standard,
which appears to specify that a conversion function will be used in
certain cases. Possibly, the draft standard is ambiguous in this area.
--
** The Klingons' favorite food was named by the first earthling to see it **
David Sachs - Fermilab, HPPC MS369 - P. O. Box 500 - Batavia, IL 60510
Voice: 1 708 840 3942 Deparment Fax: 1 708 840 3785
---
[ 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: damian@molly.cs.monash.edu.au (Damian Conway)
Date: 1995/10/19 Raw View
Various people explore various copy initialization scenarios and the rationale
for allowing optimization back to direct construction:
[deleted]
I still haven't seen a convincing explanation (pace Steve) as to why the WP
differentiates so clearly between direct and copy initialization semantics
when the real situation is (or appears to be) that direct initialization
_may_ be used in all cases, at the discretion of the compiler.
Sure, leaving the compiler the freedom to optimize out unneeded temporaries
is probably a Good Thing, even at the expense of predictability, but why
not simply word the description to reflect the fact that, when using _either_
the "()" or the "=" form of initialization, temporaries of various types
_may_ be generated (with the constraint that the direct initialization form
will not generate temporaries of the type being initialized)?
damian
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~
who: Damian Conway email: damian@bruce.cs.monash.edu.au
where: Dept. Computer Science phone: +61-3-565-5184
Monash University fax: +61-3-565-5146
Clayton 3168 quote: "A pessimist is never disappointed.
"
AUSTRALIA
---
[ 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: martelli@cadlab.cadlab.it (Alex Martelli)
Date: 1995/10/20 Raw View
b91926@fsgm01.fnal.gov (David Sachs) writes:
...
>easy to produce a case in which X x(a); and X x=a; behave differently,
>where a is a class object, of a class that has a conversion operator to
>X&, and another higher priority conversion to something accepted by a
>constructor of class X. then:
>X x(a) uses higher priority conversion by overloading rules
>X x=a uses X(a.operator X&)
I think I'm confused here -- what would be a "higher priority conversion"
from a class object a to something accepted by a constructor of class X,
than an operatorX&() member of a's class (call that class A)...?
It seems to me that the highest priority conversion of them all would
be "no conversion at all", i.e. assume class X has a constructor that
accepts an A, as in...:
class X:
class A{ public: operatorX&() const; };
class X{ public: X(const A&); X(const X&); }
Even in this case, wouldn't the two usages...:
A a;
X x1(a);
X x2=a;
just both be _ambiguous_...? I do suspect I may be somewhat
confused here, so would appreciate clarification (ideally with
draft standard chapter&verse reference, thanks!).
Alex
--
DISCLAIMER: these are TOTALLY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it Phone: +39 (51) 597313
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia Fax: +39 (51) 597120
---
[ 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: martelli@cadlab.cadlab.it (Alex Martelli)
Date: 1995/10/21 Raw View
matt@godzilla.EECS.Berkeley.EDU (Matt Austern) writes:
...
>Sort of. If a is of class A, if the copy constructor X::X(const X&)
>exists, and if the converting constructor X::X(const A&) exists and
>isn't qualified as explicit, then "X x(a)" simply invokes the
>converting constructor while "X x=a" invokes the converting
>constructor and then the copy constructor.
So, to clarify my understanding -- the following program...:
--cut tc.cc
#include <iostream.h>
class A { };
class X {
public:
X(const X&) {
cout<<"X::copy ctor"<<endl;
}
X(const A&) {
cout<<"X::ctor(A&)"<<endl;
}
};
int
main()
{
A a;
X x1 = a;
X x2(a);
return 0;
}
--end cut
... should necessarily emit:
X::ctor(A&)
X::ctor(A&)
X::copy ctor
and an implementation optimizing out the copy ctor in this case
would be non-conforming...? Oh boy, I _am_ confused -- I thought
such sentences in the draft as "Either direct-initialization semantics
or copy-initialization semantics apply" in [class.expl.init] sub 1
were there to specifically allow such optimizing-out... perhaps it
would be beneficial to the standard's clarity if this was spelled
out in as many words (or IS it there, and I'm just being unable to
see it? I still think some clarification would help...).
Alex
--
DISCLAIMER: these are TOTALLY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it Phone: +39 (51) 597313
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia Fax: +39 (51) 597120
---
[ 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: jlm@two-oo-one.fr (Jean-Louis Moser)
Date: 1995/10/13 Raw View
| According to the standard, are the two lines of the main
| equivalent ? My Opinion is yes, but one of my compilers would
| like to access copy contructor to be happy with the
| second line as if it would like to build a2 from a temporary A
| which would be build from the int value 99. If we make copy
| constructor public, this one isn't called, but the compiler
| is happy. Thank you for answers.
#include <iostream.h>
class A {
public:
A (int i) {cout << "A" << endl;}
private:
A (const A&) {cout << "COPY" << endl;}
};
void main ()
{
A a1 (100);
A a2 = 99;
}
--
+----------------------------+------------------------------------+
| Jean-Louis Moser | 2001 SA |
| tel: 33 (1)46.66.54.54 | 2, rue de la renaissance |
| Email: jlm@two-oo-one.fr | F-92184 Antony Cedex |
+----------------------------+------------------------------------+
---
[ 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: jason@cygnus.com (Jason Merrill)
Date: 1995/10/13 Raw View
>>>>> Jean-Louis Moser <jlm@two-oo-one.fr> writes:
> | According to the standard, are the two lines of the main
> | equivalent ? My Opinion is yes
Nope.
8.5 Initializers [dcl.init]
10The initialization that occurs in argument passing, function return,
throwing an exception (_except.throw_), handling an exception
(_except.handle_), and brace-enclosed initializer lists
(_dcl.init.aggr_) is called copy-initialization and is equivalent to
the form
T x = a;
The initialization that occurs in new expressions (_expr.new_),
static_cast expressions (_expr.static.cast_), functional notation type
conversions (_expr.type.conv_), and base and member initializers
(_class.base.init_) is called direct-initialization and is equivalent
to the form
T x(a);
...
--Otherwise (i.e., for the remaining copy-initialization cases), a
temporary of the destination type is created. User-defined con-
versions that can convert from the source type to the destination
type are enumerated (_over.match.user_), and the best one is cho-
sen through overload resolution (_over.match_). The user-defined
conversion so selected is called to convert the initializer
expression into the temporary. If the conversion cannot be done
or is ambiguous, the initialization is ill-formed. The object
being initialized is then direct-initialized from the temporary
according to the rules above.7) In certain cases, an implementa-
tion is permitted to eliminate the temporary by initializing the
object directly; see _class.temporary_.
Jason
---
[ 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: tony@ews360.nec.com.tw (Anthony S. H. Lee)
Date: 1995/10/14 Raw View
Jean-Louis Moser (jlm@two-oo-one.fr) wrote:
: | According to the standard, are the two lines of the main
: | equivalent ? My Opinion is yes, but one of my compilers would
: | like to access copy contructor to be happy with the
: | second line as if it would like to build a2 from a temporary A
: | which would be build from the int value 99. If we make copy
: | constructor public, this one isn't called, but the compiler
: | is happy. Thank you for answers.
: #include <iostream.h>
: class A {
: public:
: A (int i) {cout << "A" << endl;}
: private:
: A (const A&) {cout << "COPY" << endl;}
: };
: void main ()
: {
: A a1 (100);
: A a2 = 99;
: }
Have you tried to remove the copy constuctor?
You are right! S. Lippman described this characteristic in his
book, 'C++ Primer'
Your compiler may not following the C++ standard!
Can you tell us what brand it was? :)
--
! Anthony S. H. Lee [Lee, Shih Hao] Internet: tony@ews360.nec.com.tw
! BIG5:'uh;( EUC:JWDIk0 MSN: Anthony_S_H_Lee Anthony_S_H_Lee@MSN.com
! Lee-fruit, Shih-scholar, Hao-hero WWW http://necta.nec.com.tw/~tony
---
[ 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. ]