Topic: copy initialization question
Author: Anthony Williams <anthony_w@my-deja.com>
Date: 2000/07/27 Raw View
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
In article <397dd0e4.13260856@news.csrlink.net>,
jpotter@falcon.lhup.edu (John Potter) wrote:
> It is an optimization and optimizations are allowed but never
required.
> There are restrictions on when the optimization is allowed and some
> compilers get it wrong.
>
> int x = 1 is equivalent to int x(1)
> Foo y(2);
> Foo z = y is equivalent to Foo z(y)
>
> In both cases the rhs is the same type as the lhs. This case of copy
> initialization is semantically equivalent to direct initialization
> using the copy ctor.
>
> Foo w = 1 is equivalent to Foo w(Foo(1))
>
> Because the rhs is not the same type as the lhs. We may not depend
> upon the temporary being constructed and destructed, but we may depend
> on an ill-formed diagnostic when the copy ctor is private.
>
I agree entirely with your interpretation of the standard. However, it
bugs me
that in this case a temporary may or may not be constructed. This means
that
your code can have different behaviour on different implementations of
the
compiler. Here is a simple example - every constructor for a class
increments a
static class member, showing how many times an object has been
constructed. If
the compiler generates the temporary, then the count will be one more
than if
it doesn't.
Obviously, this could be extended to any other side-effects of the
constructors, which could be very wide ranging. (I could
create/delete/write to
files, send network packets or create other objects in my COPY
constructor,
which the compiler then doesn't have to call)
I just noticed that the standard explicitly says this in 12.8p15
"Whenever a temporary class object is copied using a copy constructor,
and this
object and the copy have the
same cv-unqualified type, an implementation is permitted to treat the
original
and the copy as two different
ways of referring to the same object and not perform a copy at all,
even if the
class copy constructor or
destructor have side effects."
Ouch.
Anthony
- --
alink@anthonyw.cjb.net -- Questions relating to ALINK
anthony@anthonyw.cjb.net -- Non-ALINK questions
anthonyw.cjb.net -- ALINK home page
PGP Key at: i3.yimg.com/3/c7e5ee24/g/68fc2307.asc
-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 6.5.1 for non-commercial use <http://www.pgp.com>
Comment: PGP Key at: http://i3.yimg.com/3/c7e5ee24/g/68fc2307.asc
iQA/AwUBOX6jK5vw+P4cG5rVEQL6gACfQ5j/v2/o6o8myzjYQwv54cy7Fy8AoLgI
0YKHyPe70hWiqeVxuUDyTC/s
=jEz1
-----END PGP SIGNATURE-----
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Xazziri" <xazziri@gmx.net>
Date: 2000/07/27 Raw View
"James Kuyper" <kuyper@wizard.net> wrote in message
news:397E27AA.81A3CFC8@wizard.net...
> Xazziri wrote:
> >
> > "Francis Glassborow" <francis@robinton.demon.co.uk> wrote in message
> > news:A9kFDeBoOOf5EwGe@robinton.demon.co.uk...
> > > In article <8lhe3c$1ga$1@nereid.worldonline.nl>, Xazziri
> > > <xazziri@gmx.net> writes
> > > >> This code should not compile because Foo copy ctor is
> > > >> not accessible. Even the optimization the compiler can do by
calling
> > > >> Foo(int) instead can be applied only if copy ctor is accessible.
> > > >This is not an optimization, but a requirement. The statement you
> > describe
> > > >is simply an alternate way of initializing a variable - *not* an
> > assignment
> > > >or a copy constructor call.
> > >
> > > Please spend a little time checking your facts before posting
assertions
> > > such as the above. I have left out the earlier ones because they were
> > > mostly similarly flawed.
> > >
> > Will do, if you promise to include proper references to the text in the
> > standard proving your argument. I do not doubt the fact that you have
> > 'checked your facts', but it would be nice to see it proven objectively.
>
<standard text snipped>
> Does that cover everything?
>
I believe it does, and that settles the case - I was wrong, mr. Glassborow
was right. Now, wasn't that easy? *g* In my (admittedly poor) defense,
nearly all C++ compilers have done this exact optimization for years, and a
great many of them don't bother to check accessibility of the copy
constructor (obviously because it's just extra work to them, and C++ isn't
known for holding the programmer's hand in any case).
I'm still wondering about
X.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 2000/07/28 Raw View
On Thu, 27 Jul 2000 03:21:06 CST, Anthony Williams
<anthony_w@my-deja.com> wrote:
> I just noticed that the standard explicitly says this in 12.8p15
>
> "Whenever a temporary class object is copied using a copy constructor,
> and this
> object and the copy have the
> same cv-unqualified type, an implementation is permitted to treat the
> original
> and the copy as two different
> ways of referring to the same object and not perform a copy at all,
> even if the
> class copy constructor or
> destructor have side effects."
>
> Ouch.
Yes. It must say it because it is a permitted violation of the as-if
rule. You can detect it; so, it had to be explicetly allowed. If you
do a deja search, you will find a lot of heat on this subject. A look
at the drafts of the standard will show that it was tightened some.
IV. Thow shalt not depend upon side effects of a copy-ctor.
See also NRVO currently in clc++m.
John
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Sebastian Moleski" <sebmol@gmx.net>
Date: 2000/07/25 Raw View
It's a bug in VC. Note that Microsoft's C++ compilers have never been
considered very standard-compliant. Borland's C++ compiler (93% compliant
according to the manufacturer) will not compile the code given.
Regards,
Sebastian Moleski
"Gil Shafriri" <gilsh@microsoft.com>:
> According to what I read in the standard (12.6.1) - the following code
> should not compiles :
> class Foo
> {
> public:
> Foo(int){}
> private:
> Foo(const Foo&);
> };
>
> void main(int argc, char** argv[])
> {
> Foo x = 1;
> }
>
> The compiler has to create temporary by calling Foo(int) then to copy
> initialize
> x using this temporary. This code should not compile because Foo copy ctor
> is
> not accessible. Even the optimization the compiler can do by calling
> Foo(int) instead can be
> applied only if copy ctor is accessible. However - this code compiles OK
> under vc6.
> This looks to me as compiler bug - Do I miss something ?
> Thanks,
> Gil
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Xazziri" <xazziri@gmx.net>
Date: 2000/07/25 Raw View
"Gil Shafriri" <gilsh@microsoft.com> wrote in message
news:397a0d79@news.microsoft.com...
> According to what I read in the standard (12.6.1) - the following code
> should not compiles :
> class Foo
> {
> public:
> Foo(int){}
> private:
> Foo(const Foo&);
> };
>
> void main(int argc, char** argv[])
It's int main(int argc, char* argv[]), but that's not the issue, of
course...
> {
> Foo x = 1;
> }
>
> The compiler has to create temporary by calling Foo(int) then to copy
> initialize x using this temporary.
No. This is a very common myth, but it's not true. The statement is
equivalent to
Foo x(1);
and will *not* call the copy constructor. If you'd written
Foo x;
x = 1;
*then* the copy constructor would have been called, and *then* the compiler
would rightly balk at the fact that copying isn't possible. As it is,
though, you're calling Foo(int), and not the copy constructor.
> This code should not compile because Foo copy ctor is
> not accessible. Even the optimization the compiler can do by calling
> Foo(int) instead can be applied only if copy ctor is accessible.
This is not an optimization, but a requirement. The statement you describe
is simply an alternate way of initializing a variable - *not* an assignment
or a copy constructor call.
X.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Dag Henriksson" <dag.henriksson@quidsoft.se>
Date: 2000/07/25 Raw View
> > class Foo
> > {
> > public:
> > Foo(int){}
> > private:
> > Foo(const Foo&);
> > };
> > void main(int argc, char** argv[])
> > {
> > Foo x = 1;
> > }
> > The compiler has to create temporary by calling Foo(int)
>
> Yes it calls Foo::Foo(int), but it doesnt create a temporary,
> it creates 'x' directly.
It's allowed to create x directly, but still, the copy constructor must be
accessible. (12.2p1)
> The initialization above doesn't call the copy ctor.
It's allowed to (it the copy ctor was public), but not required to.
> > Even the optimization the compiler can do by calling
> > Foo(int) instead can be
> > applied only if copy ctor is accessible. However - this code compiles OK
> > under vc6.
> > This looks to me as compiler bug - Do I miss something ?
>
> Yes, I think you missed the difference between initialization and
> assignment.
Who talked about assignment???
> Foo x =1; // initialization, not assignment
Yes...
> will be interpreted by the compiler as:
> Foo x(1); // calls public constructor
No. This is direct initialization.
Foo x=1;
is copy initialization.
> Foo x;
> Foo y;
> x = y; // tries to call incaccessible (private) copy-constructor,
No.
here the operator= is used.
-- Dag Henriksson
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/07/25 Raw View
In article <397a0d79@news.microsoft.com>, Gil Shafriri
<gilsh@microsoft.com> writes
>However - this code compiles OK
>under vc6.
>This looks to me as compiler bug - Do I miss something ?
Yes, you used MS extension that allows main to return a void so the
compiler is allowed to do what it likes (as long as, in conforming mode,
it issues a diagnostic for your use of the extension)
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/07/25 Raw View
In article <8lhe3c$1ga$1@nereid.worldonline.nl>, Xazziri
<xazziri@gmx.net> writes
>> This code should not compile because Foo copy ctor is
>> not accessible. Even the optimization the compiler can do by calling
>> Foo(int) instead can be applied only if copy ctor is accessible.
>This is not an optimization, but a requirement. The statement you describe
>is simply an alternate way of initializing a variable - *not* an assignment
>or a copy constructor call.
Please spend a little time checking your facts before posting assertions
such as the above. I have left out the earlier ones because they were
mostly similarly flawed.
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Mike Wahler" <mkwahler@mkwahler.net>
Date: 2000/07/26 Raw View
Xazziri <xazziri@gmx.net> wrote in message
news:8lhe3c$1ga$1@nereid.worldonline.nl...
> "Gil Shafriri" <gilsh@microsoft.com> wrote in message
> news:397a0d79@news.microsoft.com...
> > According to what I read in the standard (12.6.1) - the following code
> > should not compiles :
> > class Foo
> > {
> > public:
> > Foo(int){}
> > private:
> > Foo(const Foo&);
> > };
> >
> > void main(int argc, char** argv[])
> It's int main(int argc, char* argv[]), but that's not the issue, of
> course...
>
> > {
> > Foo x = 1;
> > }
> >
> > The compiler has to create temporary by calling Foo(int) then to copy
> > initialize x using this temporary.
> No. This is a very common myth, but it's not true. The statement is
> equivalent to
>
> Foo x(1);
>
> and will *not* call the copy constructor. If you'd written
>
> Foo x;
> x = 1;
>
> *then* the copy constructor would have been called,
No, it would call the assignment operator (operator=() )
The copy constructor would have a 'same-type' argument:
Foo::Foo(Foo&);
>and *then* the compiler
> would rightly balk at the fact that copying isn't possible. As it is,
> though, you're calling Foo(int), and not the copy constructor.
Agreed.
-Mike
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Mike Wahler" <mkwahler@mkwahler.net>
Date: 2000/07/26 Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote in message
news:N662iVAQRJf5EwX+@robinton.demon.co.uk...
> In article <8li0kc$1tv$1@slb7.atl.mindspring.net>, Mike Wahler
> <mkwahler@mkwahler.net> writes
> >Yes, I think you missed the difference between initialization and
> >assignment.
> >
> >Foo x =1; // initialization, not assignment
> >
> >will be interpreted by the compiler as:
> >
> >Foo x(1); // calls public constructor
> >
> >However, consider:
> >
> >Foo x;
> >Foo y;
> >x = y; // tries to call incaccessible (private) copy-constructor,
> > // so should give compile error.
Yes I realize the above is in error. I corrected it in
a subsequent post.
The above should have been:
Foo x;
Foo y(x); // calls copy constructor
x = y // calls Foo::operator=(Foo &), if defined.
// If operator= is not defined, it does a memberwise
// assignment.
>
> Unfortunately your whole response is predicated on something that is not
> true.
Other than my error above, what specifically (if anything)
are you saying is not true?
> There is a critical difference between the function form of
> initialisation and the assignment like form. The former is a direct
> call of the relevant ctor, the later can be converted to that by the
> compiler iff there is an accessible copy ctor.
Don't you mean 'acceptable constructor' ? Wouldn't a copy
ctor have to have a Foo& argument?
>The standard permits the
> actual call of the copy ctor to be elided but, at least notionally,
> initialisation is via the copy ctor applied to a notional temporary.
Yes but again, doesn't the copy constructor's argument need to
be type Foo& ??. Here it is an int, so wouldn't that need
to call a Foo::Foo(int) constructor?
>
> >
> >Output some text from your Foo::Foo(int) constructor, and
> >you'll see what I mean.
>
> No that only demonstrates that the compiler is applying a permitted
> optimisation, the OP was correct.
Optimization? Without this 'optimization,' what is the alternative?
I'm not sure I follow that.
(not trying to be argumentative, but I'm a bit disconcerted that
according to you (whose opinion I respect), I seem not to have
grasped this stuff as well as I thought. :-) )
-Mike
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: =?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@attglobal.net>
Date: 2000/07/26 Raw View
Am 25.07.00, 08:39:22, schrieb "Xazziri" <xazziri@gmx.net> zum Thema Re:=20
copy initialization question:
> "Gil Shafriri" <gilsh@microsoft.com> wrote in message
> news:397a0d79@news.microsoft.com...
> > Foo x =3D 1;
> > The compiler has to create temporary by calling Foo(int) then to copy
> > initialize x using this temporary.
> No. This is a very common myth, but it's not true. The statement is
> equivalent to
> Foo x(1);
> and will *not* call the copy constructor. If you'd written
> *then* the copy constructor would have been called, and *then* the=20
compiler
> would rightly balk at the fact that copying isn't possible. As it is,
> though, you're calling Foo(int), and not the copy constructor.
As has been pointed out in the replies to Mike Wahlers post, you have it=20
wrong - the OP is right (and, if his compiler accepts it without a=20
diagnostic, the compiler is buggy).
Foo x =3D 1;
1. if there is an implicit conversion from int to Foo, then this is=20
equivalent to=20
Foo x =3D Foo(1);
2. This in turn is equivalent to
Foo x( Foo(1) );
So conceptually: First the int is converted to a temporary Foo (using, in=
=20
this case, a non-explicit conversion constructor), then that temporary is=
=20
used to copy-initialize x.
The compiler may elide the copy, but the copy must still be legal.
'Foo x=3D 1' is called copy-initialization, 'Foo x(1)' uses=20
direct-initialization. The rules for these are different.=20
> Foo x;
> x =3D 1;
This default-initializes x and then assigns an int to it. Here no copy=20
constructor is used. The initialization uses Foo's default constructor,=20
the assignment uses an assignment operator (which may be Foo's copy=20
assignment operator).
HTH
Regards, J=F6rg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Xazziri" <xazziri@gmx.net>
Date: 2000/07/26 Raw View
"Francis Glassborow" <francis@robinton.demon.co.uk> wrote in message
news:A9kFDeBoOOf5EwGe@robinton.demon.co.uk...
> In article <8lhe3c$1ga$1@nereid.worldonline.nl>, Xazziri
> <xazziri@gmx.net> writes
> >> This code should not compile because Foo copy ctor is
> >> not accessible. Even the optimization the compiler can do by calling
> >> Foo(int) instead can be applied only if copy ctor is accessible.
> >This is not an optimization, but a requirement. The statement you
describe
> >is simply an alternate way of initializing a variable - *not* an
assignment
> >or a copy constructor call.
>
> Please spend a little time checking your facts before posting assertions
> such as the above. I have left out the earlier ones because they were
> mostly similarly flawed.
>
Will do, if you promise to include proper references to the text in the
standard proving your argument. I do not doubt the fact that you have
'checked your facts', but it would be nice to see it proven objectively.
X.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Mike Wahler" <mkwahler@mkwahler.net>
Date: 2000/07/26 Raw View
Sebastian Moleski <sebmol@gmx.net> wrote in message
news:8lhikl$uu6$1@news.online.de...
> It's a bug in VC. Note that Microsoft's C++ compilers have never been
> considered very standard-compliant. Borland's C++ compiler (93% compliant
> according to the manufacturer) will not compile the code given.
Despite VC++'s other 'warts', I don't think this is one of them.
I don't see anything here that would cause a call to a copy ctor.
A call to a ('regular') constructor with an int argument, yes.
-Mike
>
> Regards,
>
> Sebastian Moleski
>
> "Gil Shafriri" <gilsh@microsoft.com>:
> > According to what I read in the standard (12.6.1) - the following code
> > should not compiles :
> > class Foo
> > {
> > public:
> > Foo(int){}
> > private:
> > Foo(const Foo&);
> > };
> >
> > void main(int argc, char** argv[])
> > {
> > Foo x = 1;
> > }
> >
> > The compiler has to create temporary by calling Foo(int) then to copy
> > initialize
> > x using this temporary. This code should not compile because Foo copy
ctor
> > is
> > not accessible. Even the optimization the compiler can do by calling
> > Foo(int) instead can be
> > applied only if copy ctor is accessible. However - this code compiles OK
> > under vc6.
> > This looks to me as compiler bug - Do I miss something ?
> > Thanks,
> > Gil
>
>
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/07/26 Raw View
In article <8lj8ut$jcp$1@slb3.atl.mindspring.net>, Mike Wahler
<mkwahler@mkwahler.net> writes
>Optimization? Without this 'optimization,' what is the alternative?
Foo f(1);
uses a ctor that can accept an int parameter by value.
Foo f = 1;
uses the same ctor to create a temporary Foo which is then conceptually
used as an argument to an accessible copy ctor that can take a temporary
argument (and so it must be const & and NOT plain &)
The compiler is allowed by the language to optimise away that second
ctor provided that there was an accessible one of the correct type
[ Foo(Foo const &) ]
Note that this is not a compiler optimisation under the as if rule but a
language optimisation which programmers need to understand.
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/07/26 Raw View
In article <8lj8ut$jcp$1@slb3.atl.mindspring.net>, Mike Wahler
<mkwahler@mkwahler.net> writes
>Don't you mean 'acceptable constructor' ? Wouldn't a copy
>ctor have to have a Foo& argument?
I meant what I wrote, no accessible copy ctor results in assignment
style initialisation failing (even if you explicitly construct a
temporary)
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 2000/07/26 Raw View
On Tue, 25 Jul 2000 06:39:22 CST, "Xazziri" <xazziri@gmx.net> wrote:
> "Gil Shafriri" <gilsh@microsoft.com> wrote in message
> news:397a0d79@news.microsoft.com...
> > According to what I read in the standard (12.6.1) - the following code
> > should not compiles :
> > class Foo
> > {
> > public:
> > Foo(int){}
> > private:
> > Foo(const Foo&);
> > };
> >
> > Foo x = 1;
> >
> > The compiler has to create temporary by calling Foo(int) then to copy
> > initialize x using this temporary.
> No. This is a very common myth, but it's not true.
Please see the standard book of myths 8.5/12 for the syntax and
8.5/14 for the semantics.
> The statement is
> equivalent to
>
> Foo x(1);
No, the statement is equivalent to Foo x(Foo(1)). This is invalid
because the copy ctor is not accessible. See 12.2/1.
> and will *not* call the copy constructor. If you'd written
>
> Foo x;
> x = 1;
>
> *then* the copy constructor would have been called, and *then* the compiler
> would rightly balk at the fact that copying isn't possible. As it is,
> though, you're calling Foo(int), and not the copy constructor.
No. That would be x = Foo(1); The conversion ctor and assignment
operator are used. This is valid.
> > This code should not compile because Foo copy ctor is
> > not accessible. Even the optimization the compiler can do by calling
> > Foo(int) instead can be applied only if copy ctor is accessible.
> This is not an optimization, but a requirement. The statement you describe
> is simply an alternate way of initializing a variable - *not* an assignment
> or a copy constructor call.
It is an optimization and optimizations are allowed but never required.
There are restrictions on when the optimization is allowed and some
compilers get it wrong.
int x = 1 is equivalent to int x(1)
Foo y(2);
Foo z = y is equivalent to Foo z(y)
In both cases the rhs is the same type as the lhs. This case of copy
initialization is semantically equivalent to direct initialization
using the copy ctor.
Foo w = 1 is equivalent to Foo w(Foo(1))
Because the rhs is not the same type as the lhs. We may not depend
upon the temporary being constructed and destructed, but we may depend
on an ill-formed diagnostic when the copy ctor is private.
John
Note: This is a repost. One of the usenet routers is not working and
I seem to be good at getting it. The auto response from the queue
software is very helpful in these cases.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 2000/07/26 Raw View
Xazziri wrote:
>
> "Francis Glassborow" <francis@robinton.demon.co.uk> wrote in message
> news:A9kFDeBoOOf5EwGe@robinton.demon.co.uk...
> > In article <8lhe3c$1ga$1@nereid.worldonline.nl>, Xazziri
> > <xazziri@gmx.net> writes
> > >> This code should not compile because Foo copy ctor is
> > >> not accessible. Even the optimization the compiler can do by calling
> > >> Foo(int) instead can be applied only if copy ctor is accessible.
> > >This is not an optimization, but a requirement. The statement you
> describe
> > >is simply an alternate way of initializing a variable - *not* an
> assignment
> > >or a copy constructor call.
> >
> > Please spend a little time checking your facts before posting assertions
> > such as the above. I have left out the earlier ones because they were
> > mostly similarly flawed.
> >
> Will do, if you promise to include proper references to the text in the
> standard proving your argument. I do not doubt the fact that you have
> 'checked your facts', but it would be nice to see it proven objectively.
Section 8.5 p12:
"The initialization that occurs in [various cases] is called
_copy-initialization_ and is equivalent to the form
T x = a;"
p14:
"... for ... copy-initialization ... The [conversion] function selected
is called with the initializer expression as its argument; if the
function selected is a constructor, the call initializes a temporary of
the destination type. The result of the call (which is the temporary for
the constructor case) is then used to direct-initialize, according to
the rules above, the object that is the destination of the
copy-initialization. In certain cases, an implementation is permitted to
eliminate the copying inherent in this direct-initialization by
constructing the intermediate result directly into the object being
initialized; see 12.2, 12.8."
Section 12.2p1:
"... Even when the creation of the temporary object is avoided (12.8),
all the semantic restrictions must be respected as if the temporary
object was created. [_Example:_ even if the copy constructor is not
called, all the semantic restrictions, such as accessibility (clause
11), shall be satisfied.]"
Does that cover everything?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Gil Shafriri" <gilsh@microsoft.com>
Date: 2000/07/24 Raw View
According to what I read in the standard (12.6.1) - the following code
should not compiles :
class Foo
{
public:
Foo(int){}
private:
Foo(const Foo&);
};
void main(int argc, char** argv[])
{
Foo x = 1;
}
The compiler has to create temporary by calling Foo(int) then to copy
initialize
x using this temporary. This code should not compile because Foo copy ctor
is
not accessible. Even the optimization the compiler can do by calling
Foo(int) instead can be
applied only if copy ctor is accessible. However - this code compiles OK
under vc6.
This looks to me as compiler bug - Do I miss something ?
Thanks,
Gil
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Mike Wahler" <mkwahler@mkwahler.net>
Date: 2000/07/25 Raw View
Gil Shafriri <gilsh@microsoft.com> wrote in message
news:397a0d79@news.microsoft.com...
> According to what I read in the standard (12.6.1) - the following code
> should not compiles :
> class Foo
> {
> public:
> Foo(int){}
> private:
> Foo(const Foo&);
> };
>
> void main(int argc, char** argv[])
> {
> Foo x = 1;
> }
>
> The compiler has to create temporary by calling Foo(int)
Yes it calls Foo::Foo(int), but it doesnt create a temporary,
it creates 'x' directly.
>then to copy
> initialize
> x using this temporary.
There is only 'x', no temporary, thus no copy occurs.
> This code should not compile because Foo copy ctor
> is
> not accessible.
Any code that *calls* the copy constructor won't compile.
The initialization above doesn't call the copy ctor.
> Even the optimization the compiler can do by calling
> Foo(int) instead can be
> applied only if copy ctor is accessible. However - this code compiles OK
> under vc6.
> This looks to me as compiler bug - Do I miss something ?
Yes, I think you missed the difference between initialization and
assignment.
Foo x =1; // initialization, not assignment
will be interpreted by the compiler as:
Foo x(1); // calls public constructor
However, consider:
Foo x;
Foo y;
x = y; // tries to call incaccessible (private) copy-constructor,
// so should give compile error.
Output some text from your Foo::Foo(int) constructor, and
you'll see what I mean.
HTH,
-Mike
> Thanks,
> Gil
>
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/07/25 Raw View
In article <8li0kc$1tv$1@slb7.atl.mindspring.net>, Mike Wahler
<mkwahler@mkwahler.net> writes
>Yes, I think you missed the difference between initialization and
>assignment.
>
>Foo x =1; // initialization, not assignment
>
>will be interpreted by the compiler as:
>
>Foo x(1); // calls public constructor
>
>However, consider:
>
>Foo x;
>Foo y;
>x = y; // tries to call incaccessible (private) copy-constructor,
> // so should give compile error.
Unfortunately your whole response is predicated on something that is not
true. There is a critical difference between the function form of
initialisation and the assignment like form. The former is a direct
call of the relevant ctor, the later can be converted to that by the
compiler iff there is an accessible copy ctor. The standard permits the
actual call of the copy ctor to be elided but, at least notionally,
initialisation is via the copy ctor applied to a notional temporary.
>
>Output some text from your Foo::Foo(int) constructor, and
>you'll see what I mean.
No that only demonstrates that the compiler is applying a permitted
optimisation, the OP was correct.
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]