- Title
- Require direct binding of short-lived references to rvalues
- Status
- cd1
- Section
- 9.5.4 [dcl.init.ref]
- Submitter
- Raoul Gough
Created on 2002-11-14.00:00:00 last changed 217 months ago
Messages
Date: 2005-10-15.00:00:00
[Voted into WP at October 2005 meeting.]
Date: 2004-10-15.00:00:00
Proposed resolution (October, 2004): Change 9.5.4 [dcl.init.ref] bullet 5.2
sub-bullet 1 as follows: [This resolution also resolves issue 291.]
If the initializer expression is an rvalue, with T2 a class type,
and "cv1 T1 " is reference-compatible with
"cv2 T2 ", the reference is bound to the
object represented by the rvalue (see 7.2.1 [basic.lval]) or to a sub-object within that object.
in one of the following ways (the choice is
implementation-defined):
[Example:
The constructor that would be used to make the copy shall be
callable whether or not the copy is actually done.
struct A { };
struct B : public A { } b;
extern B f();
const A& rca = f (); // Bound
—end example]
Either bound to the A sub-object of the B rvalue,
// or the entire B object is copied and the reference
// is bound to the A sub-object of the copy
Date: 2004-03-15.00:00:00
Notes from the March 2004 meeting: After discussing issue 450, we
found ourselves reconsidering this, and we are now inclined to
make a change to require the direct binding in all cases,
with no restriction on long-lived references. Note that such
a change would eliminate the need for a change for
issue 291.
Date: 2003-10-15.00:00:00
Notes from October 2003 meeting: We ended up feeling that this is just one of a number of cases
of optimizations that are widely done by compilers
and allowed but not required by the standard. We don't see any
strong reason to require compilers to do this particular
optimization.
Date: 2003-04-15.00:00:00
Notes from April 2003 meeting: We agreed generally with the proposal. We were unsure about the
need for the restriction regarding long-lived references.
We will check with the proposer about that. Jason Merrill points out that the test case in
issue 86 may be a case where we
do not want to require direct binding. Further information from Rani Sharoni (April 2003): I wasn't aware about the latest suggestion of Raoul as it appears in
core issue 391. In our discussions we tried to formulate a different
proposal. The rational, as we understood, behind the implementation freedom to
make an extra copying (8.5.3/5/2/12) of the rvalue is to allow return
values in registers which on some architectures are not addressable.
The example that Raoul and I presented shows that this implementation
freedom is not always possible since we can "force" the rvalue to be
addressable using additional member function (by_ref). The example
only works for short lived rvalues and this is probably why Raoul
narrow the suggestion. I had different rational which was related to the implementation of
conditional operator in VC. It seems that when conditional operator is
involved VC does use an extra copying when the lifetime of the
temporary is extended: I don't know what the consideration behind the VC implementation was
(I saw open bug on this issue) but it convinced me to narrow the
suggestion. IMHO such limitation seems to be too strict because it might limit the
optimizer since returning class rvalues in registers might be useful
(although I'm not aware about any implementation that actually does
it). My suggestion was to forbid the extra copying if the ctor is not
viable (e.g. A::A(A&) ). In this case the implementation "freedom"
doesn't exist (since the code might not compile) and only limits the
programmer freedom (e.g. Move Constructors -
http://www.cuj.com/experts/2102/alexandr.htm [Note:
URL is now defunct; observed March,2019.]).
Core issue 291 is strongly related to
the above issue and I personally
prefer to see it resolved first. It seems that VC already supports the
resolution I prefer.
struct A { /* ctor with side effect */};
void f(A& x) {
A const& r = cond ? A(1) : x; // VC actually make an extra copy of
// the rvalue A(1)
}
Date: 2026-07-25.21:52:10
After some email exchanges with Rani Sharoni, I've come up
with the following proposal to allow reference binding to
non-copyable rvalues in some cases. Rationale and some
background appear afterwards. ---- proposal ---- Replace the section of 9.5.4 [dcl.init.ref] paragraph 5
that begins "If the initializer expression is an rvalue" with the
following: ---- rationale ---- ---- background ---- The proposal is based on a recent discussion in this
group. I originally wanted to leave the implementation free
to copy the rvalue if there was a callable copy constructor,
and only have to bind directly if none was callable.
Unfortunately, a traditional compiler can't always tell
whether a function is callable or not, e.g. if the copy
constructor is declared but not defined. Rani pointed this
out in an example, and suggested that maybe trivial copy
constructors should still be allowed (by extension, maybe
wherever the compiler can determine callability). I've gone
with this version because it's simpler, and I also figure
the "as if" rule gives the compiler some freedom with POD
types anyway.
class nc {
nc (nc const &); // private, nowhere defined
public:
nc ();
nc const &by_ref () const { return *this; }
};
void f () {
void g (nc const &);
g (nc()); // Ill-formed
g (nc().by_ref()); // Ok - binds directly to rvalue
}
Forcing a direct binding in this way is possible wherever
the lifetime of the reference does not extend beyond the
containing full expression, since the reference returned
by the member function remains valid for this long.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2008-10-05 00:00:00 | admin | set | status: wp -> cd1 |
| 2006-04-22 00:00:00 | admin | set | status: dr -> wp |
| 2005-10-22 00:00:00 | admin | set | messages: + msg1280 |
| 2005-10-22 00:00:00 | admin | set | status: ready -> dr |
| 2005-05-01 00:00:00 | admin | set | status: review -> ready |
| 2004-11-07 00:00:00 | admin | set | messages: + msg1059 |
| 2004-11-07 00:00:00 | admin | set | status: drafting -> review |
| 2004-04-09 00:00:00 | admin | set | messages: + msg978 |
| 2004-04-09 00:00:00 | admin | set | status: open -> drafting |
| 2003-11-15 00:00:00 | admin | set | messages: + msg942 |
| 2003-04-25 00:00:00 | admin | set | messages: + msg849 |
| 2002-11-14 00:00:00 | admin | create | |