Topic: P0577: No lifetime extension for xvalue .


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 24 Feb 2017 06:48:36 -0800 (PST)
Raw View
------=_Part_230_236939765.1487947716905
Content-Type: multipart/alternative;
 boundary="----=_Part_231_1663272311.1487947716905"

------=_Part_231_1663272311.1487947716905
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

P0577 (PDF) <http://wg21.link/P0577> outlines a mechanism for extending the=
=20
lifetime of a temporary.

There is a part that I don't really understand:

> *No lifetime extension for xvalue.* The authors evaluated each kind of=20
xvalue expressions, and concluded that there is no single efficient=20
mechanism to ensure all xvalues=E2=80=99 lifetimes, because xvalues are =E2=
=80=9C(maybe)=20
eXpiring=E2=80=9D by nature. On the other hand, as shown in the following e=
xamples,=20
[...] , prvalue lifetime extension can be more straightforward and more=20
efficient.

The problem is the inconsistency with lifetime extension as it currently=20
exists. Consider the two cases explained in the paper, only here, we bind=
=20
them to references:

auto &&r1 =3D f(g());
auto &&r2 =3D X().n;

For `r1`, if `f` returns an rvalue reference that refers to its parameter=
=20
or a subobject thereof, this will be a dangling reference.

But `r2` is *perfectly fine*. The lifetime of the prvalue temporary will be=
=20
extended even though we are not actually referencing it directly.=20
[class.temporary]p6:

> The temporary to which the reference is bound or the temporary that is=20
the complete object of a subobject to which the reference is bound =20
persists for the lifetime of the reference...

P0577 cites 12.2 as reference for lifetime extension.

The idea of lifetime extension should not be that you provide lifetime=20
extension for *all* xvalues. But it also shouldn't be that you provide=20
lifetime extension for prvalues. It should be that you provide lifetime=20
extension for any expression for which lifetime extension is *currently*=20
valid. It should behave *exactly* as if you had created a reference=20
variable with that expression.

It seems neat being able to define lifetime extension as prvalue->lvalue=20
conversion, which allows you to think of temporary manifestation as=20
prvalue->xvalue conversion. But the inconsistency this definition creates=
=20
is not a good thing.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/e1dd36c5-58c4-4f20-870f-d806158b1187%40isocpp.or=
g.

------=_Part_231_1663272311.1487947716905
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><a href=3D"http://wg21.link/P0577">P0577 (PDF)</a> outline=
s a mechanism for extending the lifetime of a temporary.<br><br>There is a =
part that I don&#39;t really understand:<br><br>&gt; <b>No lifetime extensi=
on for xvalue.</b> The authors evaluated each kind of xvalue expressions, a=
nd concluded that there is no single efficient mechanism to ensure all xval=
ues=E2=80=99 lifetimes, because xvalues are =E2=80=9C(maybe) eXpiring=E2=80=
=9D by nature. On the other hand, as shown in the following examples, [...]=
 , prvalue lifetime extension can be more straightforward and more efficien=
t.<br><br>The problem is the inconsistency with lifetime extension as it cu=
rrently exists. Consider the two cases explained in the paper, only here, w=
e bind them to references:<br><br><div style=3D"background-color: rgb(250, =
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wi=
dth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">r1 </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">g</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">());</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">r2 </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> X</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify">n</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div></co=
de></div><br>For `r1`, if `f` returns an rvalue reference that refers to it=
s parameter or a subobject thereof, this will be a dangling reference.<br><=
br>But `r2` is <i>perfectly fine</i>. The lifetime of the prvalue temporary=
 will be extended even though we are not actually referencing it directly. =
[class.temporary]p6:<br><br>&gt; The temporary to which the reference is bo=
und or the temporary that is the complete object of a subobject to which th=
e reference is bound=C2=A0 persists for the lifetime of the reference...<br=
><br>P0577 cites 12.2 as reference for lifetime extension.<br><br>The idea =
of lifetime extension should not be that you provide lifetime extension for=
 <i>all</i> xvalues. But it also shouldn&#39;t be that you provide lifetime=
 extension for prvalues. It should be that you provide lifetime extension f=
or any expression for which lifetime extension is <i>currently</i> valid. I=
t should behave <i>exactly</i> as if you had created a reference variable w=
ith that expression.<br><br>It seems neat being able to define lifetime ext=
ension as prvalue-&gt;lvalue conversion, which allows you to think of tempo=
rary manifestation as prvalue-&gt;xvalue conversion. But the inconsistency =
this definition creates is not a good thing.<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e1dd36c5-58c4-4f20-870f-d806158b1187%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e1dd36c5-58c4-4f20-870f-d806158b1187=
%40isocpp.org</a>.<br />

------=_Part_231_1663272311.1487947716905--

------=_Part_230_236939765.1487947716905--

.


Author: Zhihao Yuan <zy@miator.net>
Date: Fri, 24 Feb 2017 11:46:02 -0600
Raw View
On Fri, Feb 24, 2017 at 8:48 AM, Nicol Bolas <jmckesson@gmail.com> wrote:
> auto &&r2 = X().n;
>
> For `r1`, if `f` returns an rvalue reference that refers to its parameter or
> a subobject thereof, this will be a dangling reference.
>
> But `r2` is perfectly fine. The lifetime of the prvalue temporary will be
> extended even though we are not actually referencing it directly.
> [class.temporary]p6:
>
> [...]
>
> The idea of lifetime extension should not be that you provide lifetime
> extension for all xvalues. But it also shouldn't be that you provide
> lifetime extension for prvalues. It should be that you provide lifetime
> extension for any expression for which lifetime extension is currently
> valid. It should behave exactly as if you had created a reference variable
> with that expression.

I think we can find some compromise here, that is to extend
lifetime for certain xvalues that we can, but not change any
xvalue's value category, making it useful to interfaces
which do not care about value categories, and still safe in
general.  Example:

  struct X { std::string s; };
  string_view x = __extend_me X().s;  // fine, extending s

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://blog.miator.net/

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGsORuD%3DUDBc7MPKcbyH7p4B-EpN8guiw9kOQHHOTmi%2B%3DgEqzQ%40mail.gmail.com.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 24 Feb 2017 10:53:25 -0800 (PST)
Raw View
------=_Part_307_21947750.1487962405198
Content-Type: multipart/alternative;
 boundary="----=_Part_308_436960159.1487962405199"

------=_Part_308_436960159.1487962405199
Content-Type: text/plain; charset=UTF-8

On Friday, February 24, 2017 at 12:46:07 PM UTC-5, Zhihao Yuan wrote:
>
> On Fri, Feb 24, 2017 at 8:48 AM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
> > auto &&r2 = X().n;
> >
> > For `r1`, if `f` returns an rvalue reference that refers to its
> parameter or
> > a subobject thereof, this will be a dangling reference.
> >
> > But `r2` is perfectly fine. The lifetime of the prvalue temporary will
> be
> > extended even though we are not actually referencing it directly.
> > [class.temporary]p6:
> >
> > [...]
> >
> > The idea of lifetime extension should not be that you provide lifetime
> > extension for all xvalues. But it also shouldn't be that you provide
> > lifetime extension for prvalues. It should be that you provide lifetime
> > extension for any expression for which lifetime extension is currently
> > valid. It should behave exactly as if you had created a reference
> variable
> > with that expression.
>
> I think we can find some compromise here, that is to extend
> lifetime for certain xvalues that we can, but not change any
> xvalue's value category, making it useful to interfaces
> which do not care about value categories, and still safe in
> general.  Example:
>
>   struct X { std::string s; };
>   string_view x = __extend_me X().s;  // fine, extending s
>

I'm not sure why changing the value category would be problematic here.
Consider `span`; it explicitly deletes rvalue reference constructors (and
for good-yet-debatable reasons). But there should never be a case where
`as_span(register <expr>)` would *not* work. Or at least, if `register
<expr>` works, then `as_span<T>` of that should also work (assuming it's a
`span`-able type).

I would say that if `register <expr>` is applied to an expression which
*both* is not an lvalue expression and doesn't extend the lifetime of a
temporary, then it should be flat-out ill-formed.

And therefore, the resulting expression from a valid instance of `register`
is *always* an lvalue. Including `X().s`.

The idea needs to be that I can rewrite the expression as though I bound it
to a reference:

auto &&temp = X().s;
string_span x = temp; //Assuming template deduction guides and so forth.

And the result will be exactly the same.

Now, I do recognize that this could potentially be problematic in template
cases. But, at the same time, I would say that it is very rare that you
encounter a function that returns an rvalue reference when you didn't
*expect* this. When it isn't explicitly part of the function's purpose.

Also, by making it explicitly illegal to use it in such cases, we also make
it so that users don't screw up like this:

//Given a Type::getFoo() which returns a `T&&` member of that type, when
given a `this` &&.
Type().getFoo(); //Returns a dangling reference.
register Type().getFoo(); //Still returns a dangling reference, but
silently compiles.

By making that last statement explicitly il-formed, we can prevent people
from screwing that up. So while they may be confused why `register
Type().x` works when `register Type().getX()` fails, at least the compiler
tells them it won't do what they *think* it does.

Also, I thought of an interesting feature related to span: being able to
qualify function members such that, if a user uses a temporary with that
overload, then the temporary will automatically have its lifetime extended
properly. And if they use something that isn't lifetime extendable (or is
not an lvalue), then they get an error. This could be applied to `const&`
parameters just like `&&` ones.

Note that I recognize that this could lead to temporaries that last longer
than strictly necessary. But I think it's good to have a way for a function
to enforce its rules and explicitly forbid the use of objects which cannot
live beyond the lifetime of the function call.

Of course, we'd want to use the same keyword in the parameter list as we do
in expressions for lifetime extension. Unfortunately, that takes `register`
off the table. But on the plus side, the standards committee seems willing
to add keywords for less useful features like control structures for `for`,
so maybe they'd add one for this too.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0f4944b0-11a6-4220-9d48-38086babc97a%40isocpp.org.

------=_Part_308_436960159.1487962405199
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, February 24, 2017 at 12:46:07 PM UTC-5, Zhihao =
Yuan wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Fri, Feb 24, 201=
7 at 8:48 AM, Nicol Bolas &lt;<a href=3D"javascript:" target=3D"_blank" gdf=
-obfuscated-mailto=3D"XDcpZt4TAgAJ" rel=3D"nofollow" onmousedown=3D"this.hr=
ef=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javasc=
ript:&#39;;return true;">jmck...@gmail.com</a>&gt; wrote:
<br>&gt; auto &amp;&amp;r2 =3D X().n;
<br>&gt;
<br>&gt; For `r1`, if `f` returns an rvalue reference that refers to its pa=
rameter or
<br>&gt; a subobject thereof, this will be a dangling reference.
<br>&gt;
<br>&gt; But `r2` is perfectly fine. The lifetime of the prvalue temporary =
will be
<br>&gt; extended even though we are not actually referencing it directly.
<br>&gt; [class.temporary]p6:
<br>&gt;
<br>&gt; [...]
<br>&gt;
<br>&gt; The idea of lifetime extension should not be that you provide life=
time
<br>&gt; extension for all xvalues. But it also shouldn&#39;t be that you p=
rovide
<br>&gt; lifetime extension for prvalues. It should be that you provide lif=
etime
<br>&gt; extension for any expression for which lifetime extension is curre=
ntly
<br>&gt; valid. It should behave exactly as if you had created a reference =
variable
<br>&gt; with that expression.
<br>
<br>I think we can find some compromise here, that is to extend
<br>lifetime for certain xvalues that we can, but not change any
<br>xvalue&#39;s value category, making it useful to interfaces
<br>which do not care about value categories, and still safe in
<br>general. =C2=A0Example:
<br>
<br>=C2=A0 struct X { std::string s; };
<br>=C2=A0 string_view x =3D __extend_me X().s; =C2=A0// fine, extending s
<br></blockquote><div><br>I&#39;m not sure why changing the value category =
would be problematic here. Consider `span`; it explicitly deletes rvalue re=
ference constructors (and for good-yet-debatable reasons). But there should=
 never be a case where `as_span(register &lt;expr&gt;)` would <i>not</i> wo=
rk. Or at least, if `register &lt;expr&gt;` works, then `as_span&lt;T&gt;` =
of that should also work (assuming it&#39;s a `span`-able type).<br><br>I w=
ould say that if `register &lt;expr&gt;` is applied to an expression which =
<b>both</b> is not an lvalue expression and doesn&#39;t extend the lifetime=
 of a temporary, then it should be flat-out ill-formed.<br><br>And therefor=
e, the resulting expression from a valid instance of `register` is <i>alway=
s</i> an lvalue. Including `X().s`.<br><br>The idea needs to be that I can =
rewrite the expression as though I bound it to a reference:<br><br><div sty=
le=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187=
); border-style: solid; border-width: 1px; overflow-wrap: break-word;" clas=
s=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"=
><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">temp </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> X</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">().</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">s</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>string_span x </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 temp</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">//Assuming template ded=
uction guides and so forth.</span></div></code></div><br>And the result wil=
l be exactly the same.<br><br>Now, I do recognize that this could potential=
ly be problematic in template cases. But, at the same time, I would say tha=
t it is very rare that you encounter a function that returns an rvalue refe=
rence when you didn&#39;t <i>expect</i> this. When it isn&#39;t explicitly =
part of the function&#39;s purpose.<br><br>Also, by making it explicitly il=
legal to use it in such cases, we also make it so that users don&#39;t scre=
w up like this:<br><br><div style=3D"background-color: rgb(250, 250, 250); =
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; o=
verflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint=
"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"style=
d-by-prettify">//Given a Type::getFoo() which returns a `T&amp;&amp;` membe=
r of that type, when given a `this` &amp;&amp;.</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">Type</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">().</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">getFoo</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
Returns a dangling reference.</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">register</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">Type</span><span style=3D"color: #660;" class=3D"styled-by-prettify">().<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">getFoo</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">//Still returns a dangling refe=
rence, but silently compiles.</span></div></code></div><br>By making that l=
ast statement explicitly il-formed, we can prevent people from screwing tha=
t up. So while they may be confused why `register Type().x` works when `reg=
ister Type().getX()` fails, at least the compiler tells them it won&#39;t d=
o what they <i>think</i> it does.<br><br>Also, I thought of an interesting =
feature related to span: being able to qualify function members such that, =
if a user uses a temporary with that overload, then the temporary will auto=
matically have its lifetime extended properly. And if they use something th=
at isn&#39;t lifetime extendable (or is not an lvalue), then they get an er=
ror. This could be applied to `const&amp;` parameters just like `&amp;&amp;=
` ones.<br><br>Note that I recognize that this could lead to temporaries th=
at last longer than strictly necessary. But I think it&#39;s good to have a=
 way for a function to enforce its rules and explicitly forbid the use of o=
bjects which cannot live beyond the lifetime of the function call.<br><br>O=
f course, we&#39;d want to use the same keyword in the parameter list as we=
 do in expressions for lifetime extension. Unfortunately, that takes `regis=
ter` off the table. But on the plus side, the standards committee seems wil=
ling to add keywords for less useful features like control structures for `=
for`, so maybe they&#39;d add one for this too.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0f4944b0-11a6-4220-9d48-38086babc97a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0f4944b0-11a6-4220-9d48-38086babc97a=
%40isocpp.org</a>.<br />

------=_Part_308_436960159.1487962405199--

------=_Part_307_21947750.1487962405198--

.


Author: Zhihao Yuan <zy@miator.net>
Date: Fri, 24 Feb 2017 14:29:39 -0600
Raw View
--001a114b4170ce8d5d05494c96af
Content-Type: text/plain; charset=UTF-8

On Feb 24, 2017 12:53 PM, "Nicol Bolas" <jmckesson@gmail.com> wrote:


Now, I do recognize that this could potentially be problematic in template
cases.


We don't change value category nor ill-formed the program for exactly that
reason.

But, at the same time, I would say that it is very rare that you encounter
a function that returns an rvalue reference when you didn't *expect* this.


It's very possible that in a template, in some instantiations a dependent
function call returns prvalue and in some other instantiations the same
code returns xvalue.  We don't want to break your instantiations when they
are valid, so we modeled __extend_me in a way giving pure gain without hard
errors.

Also, by making it explicitly illegal to use it in such cases, we also make
it so that users don't screw up like this:

//Given a Type::getFoo() which returns a `T&&` member of that type, when
given a `this` &&.
Type().getFoo(); //Returns a dangling reference.
register Type().getFoo(); //Still returns a dangling reference, but
silently compiles.

By making that last statement explicitly il-formed, we can prevent people
from screwing that up. So while they may be confused why `register
Type().x` works when `register Type().getX()` fails, at least the compiler
tells them it won't do what they *think* it does.


Compiler can choose to warn it anyway.


Also, I thought of an interesting feature related to span: being able to
qualify function members such that, if a user uses a temporary with that
overload, then the temporary will automatically have its lifetime extended
properly. And if they use something that isn't lifetime extendable (or is
not an lvalue), then they get an error. This could be applied to `const&`
parameters just like `&&` ones.


We considered various "smart" approaches, and we chose to propose the
dumbest one -- pure manual control.  Explained in the paper.

--
Zhihao

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGsORuCo0J-kCzikOHOBk34CrPY%3D%2BD_dgF8s1yZKwVgqnHhOUg%40mail.gmail.com.

--001a114b4170ce8d5d05494c96af
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div><div class=3D"gmail_extra"><div class=3D"gmail_quote=
">On Feb 24, 2017 12:53 PM, &quot;Nicol Bolas&quot; &lt;<a href=3D"mailto:j=
mckesson@gmail.com">jmckesson@gmail.com</a>&gt; wrote:<blockquote class=3D"=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div><br>Now, I do recognize that this could potential=
ly be problematic in template cases.</div></div></blockquote></div></div></=
div><div dir=3D"auto"><br></div><div dir=3D"auto">We don&#39;t change value=
 category nor ill-formed the program for exactly that reason.</div><div dir=
=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><blockquote class=3D"quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But, at the=
 same time, I would say that it is very rare that you encounter a function =
that returns an rvalue reference when you didn&#39;t <i>expect</i> this.<br=
></div></div></blockquote></div></div></div><div dir=3D"auto"><br></div><di=
v dir=3D"auto">It&#39;s very possible that in a template, in some instantia=
tions a dependent function call returns prvalue and in some other instantia=
tions the same code returns xvalue.=C2=A0 We don&#39;t want to break your i=
nstantiations when they are valid, so we modeled __extend_me in a way givin=
g pure gain without hard errors.</div><div dir=3D"auto"><br></div><div dir=
=3D"auto"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote=
 class=3D"quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div>Also, by making it explicitly illegal t=
o use it in such cases, we also make it so that users don&#39;t screw up li=
ke this:<br><br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px" class=3D"m_-5776937=
857792764277prettyprint"><code class=3D"m_-5776937857792764277prettyprint">=
<div class=3D"m_-5776937857792764277subprettyprint"><span style=3D"color:#8=
00" class=3D"m_-5776937857792764277styled-by-prettify">//Given a Type::getF=
oo() which returns a `T&amp;&amp;` member of that type, when given a `this`=
 &amp;&amp;.</span><span style=3D"color:#000" class=3D"m_-57769378577927642=
77styled-by-prettify"><br></span><span style=3D"color:#606" class=3D"m_-577=
6937857792764277styled-by-prettify">Type</span><span style=3D"color:#660" c=
lass=3D"m_-5776937857792764277styled-by-prettify">().</span><span style=3D"=
color:#000" class=3D"m_-5776937857792764277styled-by-prettify">getFoo</span=
><span style=3D"color:#660" class=3D"m_-5776937857792764277styled-by-pretti=
fy">();</span><span style=3D"color:#000" class=3D"m_-5776937857792764277sty=
led-by-prettify"> </span><span style=3D"color:#800" class=3D"m_-57769378577=
92764277styled-by-prettify">//Returns a dangling reference.</span><span sty=
le=3D"color:#000" class=3D"m_-5776937857792764277styled-by-prettify"><br></=
span><span style=3D"color:#008" class=3D"m_-5776937857792764277styled-by-pr=
ettify">register</span><span style=3D"color:#000" class=3D"m_-5776937857792=
764277styled-by-prettify"> </span><span style=3D"color:#606" class=3D"m_-57=
76937857792764277styled-by-prettify">Type</span><span style=3D"color:#660" =
class=3D"m_-5776937857792764277styled-by-prettify">().</span><span style=3D=
"color:#000" class=3D"m_-5776937857792764277styled-by-prettify">getFoo</spa=
n><span style=3D"color:#660" class=3D"m_-5776937857792764277styled-by-prett=
ify">();</span><span style=3D"color:#000" class=3D"m_-5776937857792764277st=
yled-by-prettify"> </span><span style=3D"color:#800" class=3D"m_-5776937857=
792764277styled-by-prettify">//Still returns a dangling reference, but sile=
ntly compiles.</span></div></code></div><br>By making that last statement e=
xplicitly il-formed, we can prevent people from screwing that up. So while =
they may be confused why `register Type().x` works when `register Type().ge=
tX()` fails, at least the compiler tells them it won&#39;t do what they <i>=
think</i> it does.<br></div></div></blockquote></div></div></div><div dir=
=3D"auto"><br></div><div dir=3D"auto">Compiler can choose to warn it anyway=
..</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_ex=
tra"><div class=3D"gmail_quote"><blockquote class=3D"quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><=
div><br>Also, I thought of an interesting feature related to span: being ab=
le to qualify function members such that, if a user uses a temporary with t=
hat overload, then the temporary will automatically have its lifetime exten=
ded properly. And if they use something that isn&#39;t lifetime extendable =
(or is not an lvalue), then they get an error. This could be applied to `co=
nst&amp;` parameters just like `&amp;&amp;` ones.<br></div></div></blockquo=
te></div></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">We consi=
dered various &quot;smart&quot; approaches, and we chose to propose the dum=
best one -- pure manual control.=C2=A0 Explained in the paper.</div><div di=
r=3D"auto"><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra" =
dir=3D"auto">--</div><div class=3D"gmail_extra" dir=3D"auto">Zhihao</div></=
div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAGsORuCo0J-kCzikOHOBk34CrPY%3D%2BD_d=
gF8s1yZKwVgqnHhOUg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGsORuCo0J-k=
CzikOHOBk34CrPY%3D%2BD_dgF8s1yZKwVgqnHhOUg%40mail.gmail.com</a>.<br />

--001a114b4170ce8d5d05494c96af--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 24 Feb 2017 14:04:34 -0800 (PST)
Raw View
------=_Part_1688_646112558.1487973874948
Content-Type: multipart/alternative;
 boundary="----=_Part_1689_1664304744.1487973874949"

------=_Part_1689_1664304744.1487973874949
Content-Type: text/plain; charset=UTF-8

On Friday, February 24, 2017 at 3:29:43 PM UTC-5, Zhihao Yuan wrote:
>
> On Feb 24, 2017 12:53 PM, "Nicol Bolas" <jmck...@gmail.com <javascript:>>
> wrote:
>
>
> Now, I do recognize that this could potentially be problematic in template
> cases.
>
>
> We don't change value category nor ill-formed the program for exactly that
> reason.
>
> But, at the same time, I would say that it is very rare that you encounter
> a function that returns an rvalue reference when you didn't *expect* this.
>
>
> It's very possible that in a template, in some instantiations a dependent
> function call returns prvalue and in some other instantiations the same
> code returns xvalue.  We don't want to break your instantiations when they
> are valid, so we modeled __extend_me in a way giving pure gain without hard
> errors.
>

"Very possible" does not mean "likely", "common", or even "useful". What
would template code be doing where a dependent function call could return
either a prvalue or an xvalue, *and* you have a need to extend the lifetime
of the returned temporary?

Indeed, just think about that situation for a minute. You *don't know* if
the function returns a temporary or not, so why are you extending its
lifetime? I do not understand why I would ever write that code. I just
can't see how it makes sense to want to extend the lifetime of something
that you don't even know has a lifetime to be extended.

Can you give an example where such code actually makes sense? Where it is
actually valid and reasonable code, in both the prvalue and xvalue case?
And not an artificial, "this could work" example. I can write code where it
would technically compile and technically do something. I mean code where
it genuinely makes sense.

It should also be noted that, by not making `register X().s` an lvalue, you
*are* losing something: consistency.

auto &&x1 = X().s; //This works.
auto &&x2 = X(); //This works.

auto &&x3 = register X().s; //This works.
auto &&x4 = register X(); //This doesn't work.

`x4` fails because the result of applying `register` to a prvalue is an
lvalue. But applying `register` to an xvalue, which *also extends a
temporary*, results in an xvalue. How does that make sense?

Also, by making it explicitly illegal to use it in such cases, we also make
> it so that users don't screw up like this:
>
> //Given a Type::getFoo() which returns a `T&&` member of that type, when
> given a `this` &&.
> Type().getFoo(); //Returns a dangling reference.
> register Type().getFoo(); //Still returns a dangling reference, but
> silently compiles.
>
> By making that last statement explicitly il-formed, we can prevent people
> from screwing that up. So while they may be confused why `register
> Type().x` works when `register Type().getX()` fails, at least the compiler
> tells them it won't do what they *think* it does.
>
>
> Compiler can choose to warn it anyway.
>

You could use this same reasoning about lots of things we don't allow, like
casting away `const`-ness with `static_cast`, requiring people to use
`std::move` in order to move from lvalues, and so forth. Compilers could
have warned about those things, but we explicitly made them errors.

Why *shouldn't* we make this code an error? It seems to me that this code
is clearly not what the user wanted and will only end in tears. Undefined
behavior tears.

Is there a legitimate use for `register` when applied to an xvalue that is
not a temporary-subobject? If you can't come up with a reason why it should
be allowed, then it ought to be forbidden. After all, it's easier to allow
something later if it's forbidden than it is to forbid a bad idea after
we've proven it causes lots of problems.

Also, I thought of an interesting feature related to span: being able to
> qualify function members such that, if a user uses a temporary with that
> overload, then the temporary will automatically have its lifetime extended
> properly. And if they use something that isn't lifetime extendable (or is
> not an lvalue), then they get an error. This could be applied to `const&`
> parameters just like `&&` ones.
>
>
> We considered various "smart" approaches, and we chose to propose the
> dumbest one -- pure manual control.  Explained in the paper.
>

That's not what I get from reading the paper. The first paragraph of the
Motivation section talks about N4221. But it only mentions its deficiencies
in terms of the fact that the *only* way to benefit from that feature is to
edit the function definitions. Nowhere does your paper discuss why
providing *only* manual control is better.

It seems to me that having either mechanism alone is overall less effective
than having *both*. And your paper doesn't really address this.

Also, the idea I suggested is not particularly "smart". It makes no attempt
to follow variables through to return values and so forth. It only extends
parameters.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2bde698e-c5be-4e20-bca0-d9fa0f90af12%40isocpp.org.

------=_Part_1689_1664304744.1487973874949
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, February 24, 2017 at 3:29:43 PM UTC-5, Zhihao Y=
uan wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><d=
iv><div><div class=3D"gmail_quote">On Feb 24, 2017 12:53 PM, &quot;Nicol Bo=
las&quot; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"b_arq8scAgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javasc=
ript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;retur=
n true;">jmck...@gmail.com</a>&gt; wrote:<blockquote style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br=
>Now, I do recognize that this could potentially be problematic in template=
 cases.</div></div></blockquote></div></div></div><div dir=3D"auto"><br></d=
iv><div dir=3D"auto">We don&#39;t change value category nor ill-formed the =
program for exactly that reason.</div><div dir=3D"auto"><br></div><div dir=
=3D"auto"><div><div class=3D"gmail_quote"><blockquote style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Bu=
t, at the same time, I would say that it is very rare that you encounter a =
function that returns an rvalue reference when you didn&#39;t <i>expect</i>=
 this.<br></div></div></blockquote></div></div></div><div dir=3D"auto"><br>=
</div><div dir=3D"auto">It&#39;s very possible that in a template, in some =
instantiations a dependent function call returns prvalue and in some other =
instantiations the same code returns xvalue.=C2=A0 We don&#39;t want to bre=
ak your instantiations when they are valid, so we modeled __extend_me in a =
way giving pure gain without hard errors.</div></div></blockquote><div><br>=
&quot;Very possible&quot; does not mean &quot;likely&quot;, &quot;common&qu=
ot;, or even &quot;useful&quot;. What would template code be doing where a =
dependent function call could return either a prvalue or an xvalue, <i>and<=
/i> you have a need to extend the lifetime of the returned temporary?<br><b=
r>Indeed, just think about that situation for a minute. You <i>don&#39;t kn=
ow</i> if the function returns a temporary or not, so why are you extending=
 its lifetime? I do not understand why I would ever write that code. I just=
 can&#39;t see how it makes sense to want to extend the lifetime of somethi=
ng that you don&#39;t even know has a lifetime to be extended.<br><br>Can y=
ou give an example where such code actually makes sense? Where it is actual=
ly valid and reasonable code, in both the prvalue and xvalue case? And not =
an artificial, &quot;this could work&quot; example. I can write code where =
it would technically compile and technically do something. I mean code wher=
e it genuinely makes sense.<br><br>It should also be noted that, by not mak=
ing `register X().s` an lvalue, you <i>are</i> losing something: consistenc=
y.<br><br><div style=3D"background-color: rgb(250, 250, 250); border-color:=
 rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap:=
 break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y"><code class=3D"prettyprint"><span style=3D"color: #008;" class=3D"styled=
-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x=
1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> X</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">().</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">s</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">//This works.</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"></span></code>auto</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">x2 </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> X</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">//This works.</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">x3 </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">register</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> X</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">().</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">//This works.</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><code class=
=3D"prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">x4 </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">register</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> X</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//This doesn&#39;t work.</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify"></span></code></div></code></div><br>`x4` fails because=
 the result of applying `register` to a prvalue is an lvalue. But applying =
`register` to an xvalue, which <i>also extends a temporary</i>, results in =
an xvalue. How does that make sense?<br><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"auto"><div><div class=3D"=
gmail_quote"><blockquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div dir=3D"ltr"><div>Also, by making it explicitly i=
llegal to use it in such cases, we also make it so that users don&#39;t scr=
ew up like this:<br><br><div style=3D"background-color:rgb(250,250,250);bor=
der-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div>=
<span style=3D"color:#800">//Given a Type::getFoo() which returns a `T&amp;=
&amp;` member of that type, when given a `this` &amp;&amp;.</span><span sty=
le=3D"color:#000"><br></span><span style=3D"color:#606">Type</span><span st=
yle=3D"color:#660">().</span><span style=3D"color:#000">getFoo</span><span =
style=3D"color:#660">();</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#800">//Returns a dangling reference.</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#008">register</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Type</span><span style=3D"c=
olor:#660">().</span><span style=3D"color:#000">getFoo</span><span style=3D=
"color:#660">();</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#800">//Still returns a dangling reference, but silently compiles.</spa=
n></div></code></div><br>By making that last statement explicitly il-formed=
, we can prevent people from screwing that up. So while they may be confuse=
d why `register Type().x` works when `register Type().getX()` fails, at lea=
st the compiler tells them it won&#39;t do what they <i>think</i> it does.<=
br></div></div></blockquote></div></div></div><div dir=3D"auto"><br></div><=
div dir=3D"auto">Compiler can choose to warn it anyway.</div></div></blockq=
uote><div><br>You could use this same reasoning about lots of things we don=
&#39;t allow, like casting away `const`-ness with `static_cast`, requiring =
people to use `std::move` in order to move from lvalues, and so forth. Comp=
ilers could have warned about those things, but we explicitly made them err=
ors.<br><br>Why <i>shouldn&#39;t</i> we make this code an error? It seems t=
o me that this code is clearly not what the user wanted and will only end i=
n tears. Undefined behavior tears.<br><br>Is there a legitimate use for `re=
gister` when applied to an xvalue that is not a temporary-subobject? If you=
 can&#39;t come up with a reason why it should be allowed, then it ought to=
 be forbidden. After all, it&#39;s easier to allow something later if it&#3=
9;s forbidden than it is to forbid a bad idea after we&#39;ve proven it cau=
ses lots of problems.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"auto"><div dir=3D"auto"><div><div class=3D"gmail_quote"><=
blockquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div>Also, I thought of an interesting feature rel=
ated to span: being able to qualify function members such that, if a user u=
ses a temporary with that overload, then the temporary will automatically h=
ave its lifetime extended properly. And if they use something that isn&#39;=
t lifetime extendable (or is not an lvalue), then they get an error. This c=
ould be applied to `const&amp;` parameters just like `&amp;&amp;` ones.<br>=
</div></div></blockquote></div></div></div><div dir=3D"auto"><br></div><div=
 dir=3D"auto">We considered various &quot;smart&quot; approaches, and we ch=
ose to propose the dumbest one -- pure manual control.=C2=A0 Explained in t=
he paper.</div></div></blockquote><div><br>That&#39;s not what I get from r=
eading the paper. The first paragraph of the Motivation section talks about=
 N4221. But it only mentions its deficiencies in terms of the fact that the=
 <i>only</i> way to benefit from that feature is to edit the function defin=
itions. Nowhere does your paper discuss why providing <i>only</i> manual co=
ntrol is better.<br><br>It seems to me that having either mechanism alone i=
s overall less effective than having <i>both</i>. And your paper doesn&#39;=
t really address this.<br><br>Also, the idea I suggested is not particularl=
y &quot;smart&quot;. It makes no attempt to follow variables through to ret=
urn values and so forth. It only extends parameters.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2bde698e-c5be-4e20-bca0-d9fa0f90af12%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2bde698e-c5be-4e20-bca0-d9fa0f90af12=
%40isocpp.org</a>.<br />

------=_Part_1689_1664304744.1487973874949--

------=_Part_1688_646112558.1487973874948--

.


Author: Zhihao Yuan <zy@miator.net>
Date: Fri, 24 Feb 2017 17:00:34 -0600
Raw View
On Fri, Feb 24, 2017 at 4:04 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> Can you give an example where such code actually makes sense? Where it is
> actually valid and reasonable code, in both the prvalue and xvalue case?

I don't have such code, because my paper hasn't landed :)
Whether it's worth to address, it's question worth to ask
EWG -- maybe next meeting, since I already received
some other comments and I need to address those --
before presenting it.

>
> auto &&x1 = X().s; //This works.
> auto &&x2 = X(); //This works.
>
> auto &&x3 = register X().s; //This works.
> auto &&x4 = register X(); //This doesn't work.

auto&& binds to everything so of course x4 works.

>
> You could use this same reasoning about lots of things we don't allow, like
> casting away `const`-ness with `static_cast`, requiring people to use
> `std::move` in order to move from lvalues, and so forth. Compilers could
> have warned about those things, but we explicitly made them errors.

But you may also noticed that std::move never moves
const and we didn't make that into an error.  Move over,
it copies.  Good or bad, sometimes concerns with
generic programming out weight getting benefits in other
ways -- especially when we are not making the situation
any worse.

>
> It seems to me that having either mechanism alone is overall less effective
> than having both. And your paper doesn't really address this.

Exactly, and that is why.  Neither solely fully works, so
we propose the one which always works, and is forward
compatible with any others.

>
> Also, the idea I suggested is not particularly "smart". It makes no attempt
> to follow variables through to return values and so forth. It only extends
> parameters.

When me and Tim were designing `register` for quite a
while we had a design can do that if I understand what
you are describing correctly -- extending lifetime by
calling a function, right?  And we had a nice explanation
given existing mechanism in the language -- but we
dropped that later.  We believe that we need to do
one thing and do it well.  If we want explicit control,
we don't try to expand the scope.

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://blog.miator.net/

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGsORuD5otmjmzVgY7h35uF2PZg1wHRsMzUoHUEddtNuD-p6AA%40mail.gmail.com.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 24 Feb 2017 20:13:29 -0800 (PST)
Raw View
------=_Part_1826_1598525197.1487996009388
Content-Type: multipart/alternative;
 boundary="----=_Part_1827_780484860.1487996009389"

------=_Part_1827_780484860.1487996009389
Content-Type: text/plain; charset=UTF-8

On Friday, February 24, 2017 at 6:00:38 PM UTC-5, Zhihao Yuan wrote:
>
> On Fri, Feb 24, 2017 at 4:04 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
> > auto &&x1 = X().s; //This works.
> > auto &&x2 = X(); //This works.
> >
> > auto &&x3 = register X().s; //This works.
> > auto &&x4 = register X(); //This doesn't work.
>
> auto&& binds to everything so of course x4 works.
>

Grr. Stupid forwarding references. Consider it amended to use the
appropriate typenames then. My point was to focus on the fact that lvalues
don't bind to rvalue references, and how using `register` would extend a
temporary's lifetime, yet cannot be relied upon to provide a consistent
value category. In one case it's an lvalue, in another it's an xvalue.

>
> > You could use this same reasoning about lots of things we don't allow,
> like
> > casting away `const`-ness with `static_cast`, requiring people to use
> > `std::move` in order to move from lvalues, and so forth. Compilers could
> > have warned about those things, but we explicitly made them errors.
>
> But you may also noticed that std::move never moves
> const and we didn't make that into an error. Move over,
> it copies.


`std::move` never moves *anything*; it's just a cast. And `std::move` never
guarantees movement, since copying is valid move behavior. So I'm not sure
I see the inconsistency there.


> Good or bad, sometimes concerns with
> generic programming out weight getting benefits in other
> ways -- especially when we are not making the situation
> any worse.
>

I don't understand your reasoning. You say there are concerns with generic
programming. But at this point, these concerns are entirely imaginary;
there has been no demonstration that real, legitimate code would be unable
to use this correctly.

And if the purpose of this feature is to fix the temporary lifetime
extension problem, making a feature that still allows that problem to
manifest very easily (by putting `register` in what is undeniably the wrong
place) seems to not exactly be fixing the problem. Nor is relying on
compiler warnings (which are things compilers can already detect in most
cases); Quality of Implementation should be something you rely on as a
*last* resort, not to correct flaws in a proposal.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/77eaed66-1df2-4f01-9d94-375eb58b21dc%40isocpp.org.

------=_Part_1827_780484860.1487996009389
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, February 24, 2017 at 6:00:38 PM UTC-5, Zhihao Y=
uan wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Fri, Feb 24, 2017=
 at 4:04 PM, Nicol Bolas &lt;<a href=3D"javascript:" target=3D"_blank" gdf-=
obfuscated-mailto=3D"kc8Z9gclAgAJ" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascr=
ipt:&#39;;return true;">jmck...@gmail.com</a>&gt; wrote:
<br>&gt; auto &amp;&amp;x1 =3D X().s; //This works.
<br>&gt; auto &amp;&amp;x2 =3D X(); //This works.
<br>&gt;
<br>&gt; auto &amp;&amp;x3 =3D register X().s; //This works.
<br>&gt; auto &amp;&amp;x4 =3D register X(); //This doesn&#39;t work.
<br>
<br>auto&amp;&amp; binds to everything so of course x4 works.<br></blockquo=
te><div><br>Grr. Stupid forwarding references. Consider it amended to use t=
he appropriate typenames then. My point was to focus on the fact that lvalu=
es don&#39;t bind to rvalue references, and how using `register` would exte=
nd a temporary&#39;s lifetime, yet cannot be relied upon to provide a consi=
stent value category. In one case it&#39;s an lvalue, in another it&#39;s a=
n xvalue.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
&gt;
<br>&gt; You could use this same reasoning about lots of things we don&#39;=
t allow, like
<br>&gt; casting away `const`-ness with `static_cast`, requiring people to =
use
<br>&gt; `std::move` in order to move from lvalues, and so forth. Compilers=
 could
<br>&gt; have warned about those things, but we explicitly made them errors=
..
<br>
<br>But you may also noticed that std::move never moves
<br>const and we didn&#39;t make that into an error. Move over,
<br>it copies.</blockquote><div><br>`std::move` never moves <i>anything</i>=
; it&#39;s just a cast. And `std::move` never guarantees movement, since co=
pying is valid move behavior. So I&#39;m not sure I see the inconsistency t=
here.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Good or b=
ad, sometimes concerns with
<br>generic programming out weight getting benefits in other
<br>ways -- especially when we are not making the situation
<br>any worse.<br></blockquote><div><br>I don&#39;t understand your reasoni=
ng. You say there are concerns with generic programming. But at this point,=
 these concerns are entirely imaginary; there has been no demonstration tha=
t real, legitimate code would be unable to use this correctly.<br><br>And i=
f the purpose of this feature is to fix the temporary lifetime extension pr=
oblem, making a feature that still allows that problem to manifest very eas=
ily (by putting `register` in what is undeniably the wrong place) seems to =
not exactly be fixing the problem. Nor is relying on compiler warnings (whi=
ch are things compilers can already detect in most cases); Quality of Imple=
mentation should be something you rely on as a <i>last</i> resort, not to c=
orrect flaws in a proposal.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/77eaed66-1df2-4f01-9d94-375eb58b21dc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/77eaed66-1df2-4f01-9d94-375eb58b21dc=
%40isocpp.org</a>.<br />

------=_Part_1827_780484860.1487996009389--

------=_Part_1826_1598525197.1487996009388--

.


Author: Zhihao Yuan <zy@miator.net>
Date: Sun, 26 Feb 2017 03:18:03 -0600
Raw View
On Fri, Feb 24, 2017 at 10:13 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> You say there are concerns with generic programming. But at this point,
> these concerns are entirely imaginary; there has been no demonstration that
> real, legitimate code would be unable to use this correctly.
>
> And if the purpose of this feature is to fix the temporary lifetime
> extension problem, making a feature that still allows that problem to
> manifest very easily (by putting `register` in what is undeniably the wrong
> place) seems to not exactly be fixing the problem.

We enumerated through all the possible combinations
of the caller side's requirements on value category and
a dependent calls's value category, and find that
your suggestion gives benefit while having no real
false positive when caller side's requirements are
known.  I plan to change the current design, tentatively
to what you suggest.  Thanks, Nicol :)

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://blog.miator.net/

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGsORuBk4Gq9np6g_%3D4CiDm1cm5u3Oq9O-yVAmXvEEp0haXXmQ%40mail.gmail.com.

.