Topic: Copy constructor requirement for rvalue-reference initialization
Author: Anthony Williams <anthony.williamsNOSPAM@anthonyw.cjb.net>
Date: Fri, 18 Oct 2002 14:12:02 CST Raw View
allan_w@my-dejanews.com (Allan W) writes:
> anthony.williamsNOSPAM@anthonyw.cjb.net wrote
>>Thus binding a temporary to a reference may
>>require moving it to the non-temporary storage, or it might require moving it
>>from a register to real memory. The compiler is therefore permitted to invoke
>>the copy constructor, so it can perform such copies.
>
> I agree, but I'm curious... are you speaking hypothetically only?
Yes, but see below.
> If there is some compiler that can (at least sometimes) put a class
> into registers, I'll be very impressed. Obviously the data size would
> have to be considerably smaller than the total of all registers,
> and ideally it would have to be as small as a single register; right?
Indeed. However, I have met processors where the registers are just
addressable the same way as the rest of the accessible memory (they occupy a
reserved set of addresses), so it is feasible --- a class could even have a
valid this pointer when loaded in registers on such a processor, so it would
be able to detect if it was moved without calling the copy constructor.
Anthony
--
Anthony Williams
Senior Software Engineer, Beran Instruments Ltd.
Remove NOSPAM when replying, for timely response.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Rani Sharoni" <rani_sharoni@hotmail.com>
Date: Fri, 18 Oct 2002 14:12:35 CST Raw View
""Victor Bazarov"" <vAbazarov@dAnai.com> wrote in message
news:uqudjgalljuh50@corp.supernews.com...
> "Allan W" <allan_w@my-dejanews.com> wrote...
> > anthony.williamsNOSPAM@anthonyw.cjb.net wrote
> > > Thus binding a temporary to a reference may
> > > require moving it to the non-temporary storage, or it might require
> moving it
> > > from a register to real memory. The compiler is therefore permitted to
> invoke
> > > the copy constructor, so it can perform such copies.
> >
> > I agree, but I'm curious... are you speaking hypothetically only?
> >
> > If there is some compiler that can (at least sometimes) put a class
> > into registers, I'll be very impressed.
>
> Then you should be extremely impressed by now. Imagine a class
> that consists only of an int (some kind of ID) or a pointer
> (pimpl). Don't you think a whole object would fit in a register?
>
According to that reasoning the following well-formed code will become
ill-formed because extra copying *might* be needed for an implementation
freedom:
struct A
{
A();
A *get() { return this; }
private:
A(const A &); // no copy
};
A f();
void g(A *);
void Test()
{
g( f().get() ); // How can the returned temporary be in a register when
we are taking its address?
// &static_cast<const A &>(f()); // EDG and GCC also accept such
(ill-formed ?) code
}
I think that implementation has such freedom only when dealing with
non-class types (refer 4.1/1).
Rani
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: Sat, 19 Oct 2002 00:03:38 +0000 (UTC) Raw View
On Thu, 17 Oct 2002 22:42:20 +0000 (UTC), vAbazarov@dAnai.com ("Victor Bazarov")
wrote:
>"Allan W" <allan_w@my-dejanews.com> wrote...
>> anthony.williamsNOSPAM@anthonyw.cjb.net wrote
>> > Thus binding a temporary to a reference may
>> > require moving it to the non-temporary storage, or it might require
>moving it
>> > from a register to real memory. The compiler is therefore permitted to
>invoke
>> > the copy constructor, so it can perform such copies.
>>
>> I agree, but I'm curious... are you speaking hypothetically only?
>>
>> If there is some compiler that can (at least sometimes) put a class
>> into registers, I'll be very impressed.
>
>Then you should be extremely impressed by now. Imagine a class
>that consists only of an int (some kind of ID) or a pointer
>(pimpl). Don't you think a whole object would fit in a register?
I don't think that's an argument for disallowing passing any object
to const-ref parameter when the class lacks a copy constructor.
Instead, I think it's an example of an optimization that may be
prohibited by lack of copy constructor.
However, for small objects where this optimization might be relevant
there would seldom be any good reason to remove copy constructor,
and so, at least wrt. this example, the standard is IMHO meaningless.
Cheers,
- Alf
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Sat, 19 Oct 2002 00:04:10 +0000 (UTC) Raw View
On Fri, 18 Oct 2002 14:12:35 CST, "Rani Sharoni"
<rani_sharoni@hotmail.com> wrote:
> According to that reasoning the following well-formed code will become
> ill-formed because extra copying *might* be needed for an implementation
> freedom:
> struct A
> {
> A();
> A *get() { return this; }
> private:
> A(const A &); // no copy
> };
> A f();
> void g(A *);
> void Test()
> {
> g( f().get() ); // How can the returned temporary be in a register when
> we are taking its address?
> // &static_cast<const A &>(f()); // EDG and GCC also accept such
> (ill-formed ?) code
> }
You have neglected to define f. When you try, you will find that it
is impossible. Your code is well-formed; however, it is not usable
without f which will be ill-formed.
A f () { return A(); }
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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rani_sharoni@hotmail.com ("Rani Sharoni")
Date: Sat, 19 Oct 2002 19:52:10 +0000 (UTC) Raw View
"John Potter" <jpotter@falcon.lhup.edu> wrote in message
news:3db09d58.17018625@news.earthlink.net...
> On Fri, 18 Oct 2002 14:12:35 CST, "Rani Sharoni"
> <rani_sharoni@hotmail.com> wrote:
>
> > According to that reasoning the following well-formed code will become
> > ill-formed because extra copying *might* be needed for an implementation
> > freedom:
>
> > struct A
> > {
> > A();
> > A *get() { return this; }
> > private:
> > A(const A &); // no copy
> > };
>
> > A f();
> > void g(A *);
>
> > void Test()
> > {
> > g( f().get() ); // How can the returned temporary be in a register
when
> > we are taking its address?
> > // &static_cast<const A &>(f()); // EDG and GCC also accept such
> > (ill-formed ?) code
> > }
>
> You have neglected to define f. When you try, you will find that it
> is impossible. Your code is well-formed; however, it is not usable
> without f which will be ill-formed.
>
> A f () { return A(); }
>
> John
>
I understand your concern (although I don't think it affect the generated
code) and here is slight modification of the code:
struct A
{
A();
A *get() { return this; }
A(A &); // no copy of consts and rvalues
};
Back to the main point: how can the implementation put the returned
temporary in a register and give the this pointer valid value without extra
copying of the temporary?
I think that because the implementation isn't permited to perform extra
copying in such cases then the following bindings should be allowed
(directly):
const A &x = f();
static_cast<const A &>(f()); // EDG and GCC already "allows" this one
void g(const A &);
g(f()); // this direct binding is badly needed
The motivation is to allow a binding of rvalue to const reference in *any*
case.
If no copy constructor is viable, after overloading, then the extra copy is
not semantically required which makes the above bindings possible. The
implementation is allowed to perform the extra copy only when it's possible.
Rani
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: RaoulGough@yahoo.co.uk ("Raoul Gough")
Date: Mon, 21 Oct 2002 17:06:36 +0000 (UTC) Raw View
<anthony.williamsNOSPAM@anthonyw.cjb.net> wrote in message
news:7kghtmz2.fsf@anthonyw.cjb.net...
> RaoulGough@yahoo.co.uk ("Raoul Gough") writes:
[snip]
> > So, why should the compiler ever *need* the copy constructor when
> > binding a reference (as opposed to maybe wanting to use it if
> > it's available)? Aren't there at least some cases where a copy
> > constructor call is never necessary?
>
> There _are_ cases where the copy constructor is not necessary, hence
the
> compiler is allowed, but not required, to invoke the copy
> constructor. However, this depends on the compiler, not the C++
construct
> used. For example, the compiler is allowed to allocate temporaries
in a
> separate place to non-temporaries. Thus binding a temporary to a
reference may
> require moving it to the non-temporary storage, or it might require
moving it
> from a register to real memory.
Interesting. However, by this argument the compiler must still be able
to create *some* temporaries in real memory. Similarly, it must be
able to pass the copy constructor a reference to the register (like
note 93 in the standard says, eventually it must choose to bind
directly).
> The compiler is therefore permitted to invoke
> the copy constructor, so it can perform such copies. Thus the copy
constructor
> must be accessible in all cases, to allow compilers this freedom.
Isn't this simply a matter of the compiler deciding whether an
optimization is valid in a given case? If it has to pass the object in
a normal memory location, then it could choose to create the initial
temporary in the "right" place. If there is no copy constructor
available, then the choice would be clear.
Obviously, there are existing implementations that do avoid the copy
in specific cases (at least, I'm assuming that g++ does what I expect
when it allows the ill-formed code :-). Unless there are some
architectural issues involved, other compilers would be able to do the
same. The next question would be whether it is worth enumerating these
cases in the standard, and allowing them even when no copy constructor
is available.
I'm assuming that there are some cases where a copy is difficult or
impossible for the compiler to avoid, although I don't really have a
specific example in mind. An implicit constructor call seems to throw
g++, anyway.
Regards,
Raoul Gough.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: vAbazarov@dAnai.com ("Victor Bazarov")
Date: Mon, 21 Oct 2002 17:09:24 +0000 (UTC) Raw View
"Rani Sharoni" <rani_sharoni@hotmail.com> wrote...
>
> ""Victor Bazarov"" <vAbazarov@dAnai.com> wrote in message
> news:uqudjgalljuh50@corp.supernews.com...
> > "Allan W" <allan_w@my-dejanews.com> wrote...
> > > anthony.williamsNOSPAM@anthonyw.cjb.net wrote
> > > > Thus binding a temporary to a reference may
> > > > require moving it to the non-temporary storage, or it might require
> > moving it
> > > > from a register to real memory. The compiler is therefore permitted
to
> > invoke
> > > > the copy constructor, so it can perform such copies.
> > >
> > > I agree, but I'm curious... are you speaking hypothetically only?
> > >
> > > If there is some compiler that can (at least sometimes) put a class
> > > into registers, I'll be very impressed.
> >
> > Then you should be extremely impressed by now. Imagine a class
> > that consists only of an int (some kind of ID) or a pointer
> > (pimpl). Don't you think a whole object would fit in a register?
> >
> According to that reasoning the following well-formed code will become
> ill-formed because extra copying *might* be needed for an implementation
> freedom:
It would, I suppose.
> struct A
> {
> A();
> A *get() { return this; }
> private:
> A(const A &); // no copy
> };
>
> A f();
> void g(A *);
>
> void Test()
> {
> g( f().get() ); // How can the returned temporary be in a register
when
> we are taking its address?
OK, I'll play. It's not. Did I say that it _has_ to be? I
thought we were talking of a possibility. The possibility
exists.
> // &static_cast<const A &>(f()); // EDG and GCC also accept such
> (ill-formed ?) code
> }
>
> I think that implementation has such freedom only when dealing with
> non-class types (refer 4.1/1).
I am sorry, I must be dumb or something. The 4.1/1 says that
an lvalue _can_ be converted into an rvalue. If the lvalue is of
type T, and it is a class type, then the rvalue is of type T.
What is there in 4.1/1 that _mandates_ the compiler to convert
an lvalue into an rvalue?
Speaking of storing temporaries in a register, the compiler can
see that the result is used to obtain an address of, so it can
create the code to generate the temporary in a memory location
and the copy c-tor would not be used because of RVO. f() would
create its object directly in that memory location (12.8/15).
If such compiler cannot do it without copying, then since the
copy constructor is unavailable, the code is ill-formed, yes.
Well, of course, I may not understand the RVO, or how compilers
work, so take my ramblings with a handful of salt.
Victor
--
Please remove capital A's from my address when replying by mail
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: RaoulGough@yahoo.co.uk ("Raoul Gough")
Date: Mon, 21 Oct 2002 17:16:36 +0000 (UTC) Raw View
"John Potter" <jpotter@falcon.lhup.edu> wrote in message
news:3db09d58.17018625@news.earthlink.net...
> On Fri, 18 Oct 2002 14:12:35 CST, "Rani Sharoni"
> <rani_sharoni@hotmail.com> wrote:
>
> > According to that reasoning the following well-formed code will
become
> > ill-formed because extra copying *might* be needed for an
implementation
> > freedom:
>
> > struct A
> > {
> > A();
> > A *get() { return this; }
> > private:
> > A(const A &); // no copy
> > };
>
> > A f();
> > void g(A *);
>
> > void Test()
> > {
> > g( f().get() ); // How can the returned temporary be in a
register when
> > we are taking its address?
> > // &static_cast<const A &>(f()); // EDG and GCC also accept
such
> > (ill-formed ?) code
> > }
>
> You have neglected to define f. When you try, you will find that it
> is impossible. Your code is well-formed; however, it is not usable
> without f which will be ill-formed.
>
> A f () { return A(); }
I don't think that's a fundamental problem, since A f() could be made
a friend or a static member. I *think* I'm right in assuming that only
the called function, not the caller, requires access to a copy
constructor in order to return by value. What you can do with the
returned object in this case is necessarily limited (for instance, you
don't seem to be allowed to take a reference to it) but I guess you're
allowed to call a member function on it (whether it's in a register or
not, but that would be a tough optimization if the copy constructor is
non-trivial).
Maybe it would help if I showed some real code that causes an issue
here:
template<typename T>
class proxy {
boost::mutex::scoped_lock mLock;
T *mPtr;
public:
proxy (holder<T> &);
T *get() const;
};
Where holder<T> owns a T and a mutex, and scoped_lock is noncopyable,
which means that the proxy is as well. What I would like is for the
following to work (assuming suitable overloads of operator<<):
(proxy<std::ostream> (logStream))
<< "Hello world"
<< std::endl;
Unfortunately, this doesn't work with the unnamed temporary, because
operator<< can't accept a reference to it (const or not).
A small extension to the proxy class, adding a non-const copy
constructor, allows a function to return the proxy by value (from a
_named_ temporary) but the caller can't actually do very much with the
return value. The following sort of code works fine under g++ but it
turns out not to be standards-conforming:
logStream() << "Hello" << std::endl;
I don't know how hard it is for compilers to make this work - maybe it
requires the NRVO? Anyway, I see the case where the *caller*
constructs the temporary as trivial. In fact, it is probably harder
for the compiler to construct the temporary in the _wrong_ place and
then copy it before passing a reference to it. At least in this case,
I can't see why a noncopyable rvalue can't be passed by reference.
Actually, if you can call a member function on it...
Regards,
Raoul Gough.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: RaoulGough@yahoo.co.uk ("Raoul Gough")
Date: Thu, 17 Oct 2002 01:20:31 +0000 (UTC) Raw View
I'm trying to understand the requirement in 8.5.3/5, where it states
that the implementation may copy an rvalue when initializing a
reference, and that a copy constructor must therefore be available in
all cases (i.e. even if the implementation chooses not to use it).
If I understand this restriction correctly, both references in the
following code are ill-formed:
struct noncopyable {
noncopyable(int);
private:
noncopyable (noncopyable const &);
};
void bar () {
noncopyable const &r1 = 2;
noncopyable const &r2 = noncopyable(1);
}
FWIW, g++ 3.1 complains about r1, "`noncopyable::noncopyable(const
noncopyable&)' is private", but not r2.
I've searched through this group's archive on Google, and questions
about this kind of thing have been raised before but I haven't
yet found a convincing explanation about this example.
So, why should the compiler ever *need* the copy constructor when
binding a reference (as opposed to maybe wanting to use it if
it's available)? Aren't there at least some cases where a copy
constructor call is never necessary?
Regards,
Raoul Gough.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: anthony.williamsNOSPAM@anthonyw.cjb.net
Date: Thu, 17 Oct 2002 15:00:50 +0000 (UTC) Raw View
RaoulGough@yahoo.co.uk ("Raoul Gough") writes:
> I'm trying to understand the requirement in 8.5.3/5, where it states
> that the implementation may copy an rvalue when initializing a
> reference, and that a copy constructor must therefore be available in
> all cases (i.e. even if the implementation chooses not to use it).
>
> If I understand this restriction correctly, both references in the
> following code are ill-formed:
>
> struct noncopyable {
> noncopyable(int);
> private:
> noncopyable (noncopyable const &);
> };
>
> void bar () {
> noncopyable const &r1 = 2;
> noncopyable const &r2 = noncopyable(1);
> }
>
> FWIW, g++ 3.1 complains about r1, "`noncopyable::noncopyable(const
> noncopyable&)' is private", but not r2.
Your interpretation is correct, g++ is in error.
> So, why should the compiler ever *need* the copy constructor when
> binding a reference (as opposed to maybe wanting to use it if
> it's available)? Aren't there at least some cases where a copy
> constructor call is never necessary?
There _are_ cases where the copy constructor is not necessary, hence the
compiler is allowed, but not required, to invoke the copy
constructor. However, this depends on the compiler, not the C++ construct
used. For example, the compiler is allowed to allocate temporaries in a
separate place to non-temporaries. Thus binding a temporary to a reference may
require moving it to the non-temporary storage, or it might require moving it
from a register to real memory. The compiler is therefore permitted to invoke
the copy constructor, so it can perform such copies. Thus the copy constructor
must be accessible in all cases, to allow compilers this freedom.
HTH
Anthony
--
Anthony Williams
Senior Software Engineer, Beran Instruments Ltd.
Remove NOSPAM when replying, for timely response.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rani_sharoni@hotmail.com ("Rani Sharoni")
Date: Thu, 17 Oct 2002 18:36:40 +0000 (UTC) Raw View
""Raoul Gough"" <RaoulGough@yahoo.co.uk> wrote in message
news:aol2ut$nj27r$1@ID-136218.news.dfncis.de...
> I'm trying to understand the requirement in 8.5.3/5, where it states
> that the implementation may copy an rvalue when initializing a
> reference, and that a copy constructor must therefore be available in
> all cases (i.e. even if the implementation chooses not to use it).
>
> If I understand this restriction correctly, both references in the
> following code are ill-formed:
>
> struct noncopyable {
> noncopyable(int);
> private:
> noncopyable (noncopyable const &);
> };
>
> void bar () {
> noncopyable const &r1 = 2;
> noncopyable const &r2 = noncopyable(1);
> }
>
> FWIW, g++ 3.1 complains about r1, "`noncopyable::noncopyable(const
> noncopyable&)' is private", but not r2.
>
> I've searched through this group's archive on Google, and questions
> about this kind of thing have been raised before but I haven't
> yet found a convincing explanation about this example.
>
Try open core issue -
Overload resolution needed when binding reference to class rvalue:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#291
I hope that someday it will become a DR.
> So, why should the compiler ever *need* the copy constructor when
> binding a reference (as opposed to maybe wanting to use it if
> it's available)? Aren't there at least some cases where a copy
> constructor call is never necessary?
>
I agree that this is one of those annoying cases (8.5.3/5 bullet 2/1) where
*unused* "implementation freedom" overshadows the usability of the language.
Rani
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rani_sharoni@hotmail.com ("Rani Sharoni")
Date: Thu, 17 Oct 2002 18:37:17 +0000 (UTC) Raw View
<anthony.williamsNOSPAM@anthonyw.cjb.net> wrote in message
news:7kghtmz2.fsf@anthonyw.cjb.net...
> >
> > struct noncopyable {
> > noncopyable(int);
> > private:
> > noncopyable (noncopyable const &);
> > };
> >
>
> There _are_ cases where the copy constructor is not necessary, hence the
> compiler is allowed, but not required, to invoke the copy
> constructor. However, this depends on the compiler, not the C++ construct
> used. For example, the compiler is allowed to allocate temporaries in a
> separate place to non-temporaries. Thus binding a temporary to a reference
may
> require moving it to the non-temporary storage, or it might require moving
it
> from a register to real memory. The compiler is therefore permitted to
invoke
> the copy constructor, so it can perform such copies. Thus the copy
constructor
> must be accessible in all cases, to allow compilers this freedom.
>
I just wonder how much "implementation freedom" is needed when EDG compiles
the following code:
void f(noncopyable const &);
void Test()
{
// f(noncopyable(1)); - ill-formed
f(static_cast<const noncopyable &>(noncopyable(1)));
}
Is it legal?
I (and VC7.1 beta) think that it ins't (but EDG knows better) and anyway
it's just revels how much this "implementation freedom" (with usability
cost) is really needed.
I hope that core issue #291 will become DR resulting with "programmer
freedom".
Rani
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 17 Oct 2002 21:40:22 +0000 (UTC) Raw View
anthony.williamsNOSPAM@anthonyw.cjb.net wrote
> Thus binding a temporary to a reference may
> require moving it to the non-temporary storage, or it might require moving it
> from a register to real memory. The compiler is therefore permitted to invoke
> the copy constructor, so it can perform such copies.
I agree, but I'm curious... are you speaking hypothetically only?
If there is some compiler that can (at least sometimes) put a class
into registers, I'll be very impressed. Obviously the data size would
have to be considerably smaller than the total of all registers,
and ideally it would have to be as small as a single register; right?
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: vAbazarov@dAnai.com ("Victor Bazarov")
Date: Thu, 17 Oct 2002 22:42:20 +0000 (UTC) Raw View
"Allan W" <allan_w@my-dejanews.com> wrote...
> anthony.williamsNOSPAM@anthonyw.cjb.net wrote
> > Thus binding a temporary to a reference may
> > require moving it to the non-temporary storage, or it might require
moving it
> > from a register to real memory. The compiler is therefore permitted to
invoke
> > the copy constructor, so it can perform such copies.
>
> I agree, but I'm curious... are you speaking hypothetically only?
>
> If there is some compiler that can (at least sometimes) put a class
> into registers, I'll be very impressed.
Then you should be extremely impressed by now. Imagine a class
that consists only of an int (some kind of ID) or a pointer
(pimpl). Don't you think a whole object would fit in a register?
> Obviously the data size would
> have to be considerably smaller than the total of all registers,
> and ideally it would have to be as small as a single register; right?
Right.
Victor
--
Please remove capital A's from my address when replying by mail
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Raoul Gough" <RaoulGough@yahoo.co.uk>
Date: Fri, 18 Oct 2002 10:40:19 CST Raw View
""Rani Sharoni"" <rani_sharoni@hotmail.com> wrote in message
news:3daef8cf@news.microsoft.com...
>
> ""Raoul Gough"" <RaoulGough@yahoo.co.uk> wrote in message
> news:aol2ut$nj27r$1@ID-136218.news.dfncis.de...
> > I'm trying to understand the requirement in 8.5.3/5, where it
states
> > that the implementation may copy an rvalue when initializing a
> > reference, and that a copy constructor must therefore be available
in
> > all cases (i.e. even if the implementation chooses not to use it).
[snip]
> Try open core issue -
> Overload resolution needed when binding reference to class rvalue:
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#291
>
> I hope that someday it will become a DR.
It's definitely related, but I'm not sure that resolving this issue
would make the copy constructor unnecessary. Wouldn't it just specify
more exactly how the construction of the temporary's copy is
performed?
>
> > So, why should the compiler ever *need* the copy constructor when
> > binding a reference (as opposed to maybe wanting to use it if
> > it's available)? Aren't there at least some cases where a copy
> > constructor call is never necessary?
> >
> I agree that this is one of those annoying cases (8.5.3/5 bullet
2/1) where
> *unused* "implementation freedom" overshadows the usability of the
language.
Yes. I'm yet to understand why the _programmer's_ freedom is
restricted in this case. After all, passing by const reference is
mainly (maybe even exclusively) designed to _avoid_ copying, right?
Yet in the cases where no copy constructor is available, you can't
pass an rvalue by const reference (you certainly can't pass it by
value, so you actually can't do much of anything with it except call
a member function). Maybe it's impossible to avoid this restriction
in all cases, but surely there are some cases where it can be avoided.
Regards,
Raoul Gough.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]