Topic: ref qualifiers for the standard library (again)


Author: Nicolas Lesser <blitzrakete@gmail.com>
Date: Mon, 13 Nov 2017 09:42:41 -0800 (PST)
Raw View
------=_Part_8266_1800623137.1510594961527
Content-Type: multipart/alternative;
 boundary="----=_Part_8267_1192127800.1510594961527"

------=_Part_8267_1192127800.1510594961527
Content-Type: text/plain; charset="UTF-8"

I propose to add some ref qualifiers to functions in the standard library,
just like N2819 <https://wg21.link/n2819> did in 2009, but for even more
functions. The LWG decided against that paper, and I can't find out why.
The advantage here is that the compiler will error out when trying to call
a function on an object of the wrong value category. This can prevent
subtle bugs from creeping it (due to invalidation) and operations which do
nothing (because the temporary for example gets destructed immediately).
Here are the main types of functions that I want to see with a ref
qualifier:

P.S: I know that I'm generalizing a bit, and as mentioned in N2819, there
are some classes for which those should no apply, but for most of them,
they do (just ignore those types for a moment).

1) & for assignments operators
Those should be obvious. It makes no sense whatsoever to assign a value to
a temporary (like a std::vector)

#include <vector>

std::vector<int> foo() { return {}; }

int main() {
    foo() = {1, 2}; // what??
}

gcc and clang don't generate any warnings on one of the highest warning
levels possible (https://godbolt.org/g/dSXyDJ), even though this code
basically does nothing.

2) & for strings (and views) and other containers

There was a recent question on SO on them
(https://stackoverflow.com/questions/47261061/stdstring-view-on-temporary-string-catch-by-asan).
The problem there is that std::string has a conversion operator to a
std::string_view, and if the std::string is a temporary, then the returned
std::string_view is invalid soon after. The same thing can happen for c_str
and data, but more obvious. From the SO question:

#include <string>
#include <string_view>
#include <iostream>

std::string foo() {
    return "test";
}

int main() {
    std::string_view bar = foo(); // bar is pointed to destructed string
    std::cout << bar << std::endl;
}

If the conversion operator would have been marked with a &, this would not
have happened. This also doesn't hurt for c_str() and data() (which would
apply to other containers like std::vector as well) too.

What do you think?

--
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/3f41db92-4c4a-400e-8981-456aaab8af07%40isocpp.org.

------=_Part_8267_1192127800.1510594961527
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I propose to add some ref qualifiers to functions in the s=
tandard library, just like=C2=A0<a href=3D"https://wg21.link/n2819">N2819</=
a>=C2=A0did in 2009, but for even more functions. The LWG decided against t=
hat paper, and I can&#39;t find out why. The advantage here is that the com=
piler will error out when trying to call a function on an object of the wro=
ng value category. This can prevent subtle bugs from creeping it (due to in=
validation) and operations which do nothing (because the temporary for exam=
ple gets destructed immediately). Here are the main types of functions that=
 I want to see with a ref qualifier:<div><br></div><div>P.S: I know that I&=
#39;m generalizing a bit, and as mentioned in N2819, there are some classes=
 for which those should no apply, but for most of them, they do (just ignor=
e those types for a moment).</div><div><br></div><div>1) &amp; for assignme=
nts operators</div><div>Those should be obvious. It makes no sense whatsoev=
er to assign a value to a temporary (like a std::vector)</div><div><br></di=
v><div>#include &lt;vector&gt;</div><div><br></div><div>std::vector&lt;int&=
gt; foo() { return {}; }</div><div><br></div><div>int main() {<br>=C2=A0 =
=C2=A0 foo() =3D {1, 2}; // what??</div><div>}</div><div><br></div><div>gcc=
 and clang don&#39;t generate any warnings on one of the highest warning le=
vels possible (https://godbolt.org/g/dSXyDJ), even though this code basical=
ly does nothing.=C2=A0</div><div><br></div><div>2) &amp; for strings (and v=
iews) and other containers</div><div><br></div><div>There was a recent ques=
tion on SO on them (https://stackoverflow.com/questions/47261061/stdstring-=
view-on-temporary-string-catch-by-asan). The problem there is that std::str=
ing has a conversion operator to a std::string_view, and if the std::string=
 is a temporary, then the returned std::string_view is invalid soon after. =
The same thing can happen for c_str and data, but more obvious. From the SO=
 question:</div><div><br></div><div>#include &lt;string&gt;</div><div>#incl=
ude &lt;string_view&gt;</div><div>#include &lt;iostream&gt;</div><div><br><=
/div><div>std::string foo() {</div><div>=C2=A0 =C2=A0 return &quot;test&quo=
t;;</div><div>}</div><div><br></div><div>int main() {<br>=C2=A0 =C2=A0 std:=
:string_view bar =3D foo(); // bar is pointed to destructed string</div><di=
v>=C2=A0 =C2=A0 std::cout &lt;&lt; bar &lt;&lt; std::endl;</div><div>}</div=
><div><br></div><div>If the conversion operator would have been marked with=
 a &amp;, this would not have happened. This also doesn&#39;t hurt for c_st=
r() and data() (which would apply to other containers like std::vector as w=
ell) too.</div><div><br></div><div>What do you think?</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/3f41db92-4c4a-400e-8981-456aaab8af07%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3f41db92-4c4a-400e-8981-456aaab8af07=
%40isocpp.org</a>.<br />

------=_Part_8267_1192127800.1510594961527--

------=_Part_8266_1800623137.1510594961527--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 13 Nov 2017 10:25:17 -0800 (PST)
Raw View
------=_Part_4722_486267311.1510597517428
Content-Type: multipart/alternative;
 boundary="----=_Part_4723_1961309150.1510597517428"

------=_Part_4723_1961309150.1510597517428
Content-Type: text/plain; charset="UTF-8"



On Monday, November 13, 2017 at 12:42:41 PM UTC-5, Nicolas Lesser wrote:
>
> I propose to add some ref qualifiers to functions in the standard library,
> just like N2819 <https://wg21.link/n2819> did in 2009, but for even more
> functions. The LWG decided against that paper, and I can't find out why.
> The advantage here is that the compiler will error out when trying to call
> a function on an object of the wrong value category. This can prevent
> subtle bugs from creeping it (due to invalidation) and operations which do
> nothing (because the temporary for example gets destructed immediately).
> Here are the main types of functions that I want to see with a ref
> qualifier:
>
> P.S: I know that I'm generalizing a bit, and as mentioned in N2819, there
> are some classes for which those should no apply, but for most of them,
> they do (just ignore those types for a moment).
>
> 1) & for assignments operators
> Those should be obvious. It makes no sense whatsoever to assign a value to
> a temporary (like a std::vector)
>
> #include <vector>
>
> std::vector<int> foo() { return {}; }
>
> int main() {
>     foo() = {1, 2}; // what??
> }
>
> gcc and clang don't generate any warnings on one of the highest warning
> levels possible (https://godbolt.org/g/dSXyDJ), even though this code
> basically does nothing.
>
> 2) & for strings (and views) and other containers
>
> There was a recent question on SO on them (
> https://stackoverflow.com/questions/47261061/stdstring-view-on-temporary-string-catch-by-asan).
> The problem there is that std::string has a conversion operator to a
> std::string_view, and if the std::string is a temporary, then the returned
> std::string_view is invalid soon after. The same thing can happen for c_str
> and data, but more obvious. From the SO question:
>
> #include <string>
> #include <string_view>
> #include <iostream>
>
> std::string foo() {
>     return "test";
> }
>
> int main() {
>     std::string_view bar = foo(); // bar is pointed to destructed string
>     std::cout << bar << std::endl;
> }
>
> If the conversion operator would have been marked with a &, this would not
> have happened.
>

And neither would this:

void some_func(std::string_view view);

some_func(foo());

Yet this is perfectly valid.

C++ has no good solution to this problem. You're either going to forbid
legitimate code, or allow broken code. We do not have any mechanism at
present that allows us to determine when such things are being used
legitimately and when they are not.

--
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/c3e093a8-05e2-4047-9079-c8356d7f12df%40isocpp.org.

------=_Part_4723_1961309150.1510597517428
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Monday, November 13, 2017 at 12:42:41 PM UTC-5,=
 Nicolas Lesser 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"ltr">I propose to add some ref qualifiers to functions in the standard =
library, just like=C2=A0<a href=3D"https://wg21.link/n2819" target=3D"_blan=
k" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.com/=
url?q\x3dhttps%3A%2F%2Fwg21.link%2Fn2819\x26sa\x3dD\x26sntz\x3d1\x26usg\x3d=
AFQjCNGLLkAUjQYsHGnO5YMbK628zQBkGw&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwg21.link%2Fn2819\x26=
sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGLLkAUjQYsHGnO5YMbK628zQBkGw&#39;;retu=
rn true;">N2819</a>=C2=A0did in 2009, but for even more functions. The LWG =
decided against that paper, and I can&#39;t find out why. The advantage her=
e is that the compiler will error out when trying to call a function on an =
object of the wrong value category. This can prevent subtle bugs from creep=
ing it (due to invalidation) and operations which do nothing (because the t=
emporary for example gets destructed immediately). Here are the main types =
of functions that I want to see with a ref qualifier:<div><br></div><div>P.=
S: I know that I&#39;m generalizing a bit, and as mentioned in N2819, there=
 are some classes for which those should no apply, but for most of them, th=
ey do (just ignore those types for a moment).</div><div><br></div><div>1) &=
amp; for assignments operators</div><div>Those should be obvious. It makes =
no sense whatsoever to assign a value to a temporary (like a std::vector)</=
div><div><br></div><div>#include &lt;vector&gt;</div><div><br></div><div>st=
d::vector&lt;int&gt; foo() { return {}; }</div><div><br></div><div>int main=
() {<br>=C2=A0 =C2=A0 foo() =3D {1, 2}; // what??</div><div>}</div><div><br=
></div><div>gcc and clang don&#39;t generate any warnings on one of the hig=
hest warning levels possible (<a href=3D"https://godbolt.org/g/dSXyDJ" targ=
et=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.=
google.com/url?q\x3dhttps%3A%2F%2Fgodbolt.org%2Fg%2FdSXyDJ\x26sa\x3dD\x26sn=
tz\x3d1\x26usg\x3dAFQjCNF6MgKxjFzeKSkzk97__06L-59v9A&#39;;return true;" onc=
lick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgodb=
olt.org%2Fg%2FdSXyDJ\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF6MgKxjFzeKSkz=
k97__06L-59v9A&#39;;return true;">https://godbolt.org/g/dSXyDJ</a>)<wbr>, e=
ven though this code basically does nothing.=C2=A0</div><div><br></div><div=
>2) &amp; for strings (and views) and other containers</div><div><br></div>=
<div>There was a recent question on SO on them (<a href=3D"https://stackove=
rflow.com/questions/47261061/stdstring-view-on-temporary-string-catch-by-as=
an" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http=
s://www.google.com/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F4=
7261061%2Fstdstring-view-on-temporary-string-catch-by-asan\x26sa\x3dD\x26sn=
tz\x3d1\x26usg\x3dAFQjCNGzMoXxGWkDxq0Wj8vMwpvAcWMwCw&#39;;return true;" onc=
lick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fstac=
koverflow.com%2Fquestions%2F47261061%2Fstdstring-view-on-temporary-string-c=
atch-by-asan\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGzMoXxGWkDxq0Wj8vMwpvA=
cWMwCw&#39;;return true;">https://stackoverflow.com/<wbr>questions/47261061=
/stdstring-<wbr>view-on-temporary-string-<wbr>catch-by-asan</a>). The probl=
em there is that std::string has a conversion operator to a std::string_vie=
w, and if the std::string is a temporary, then the returned std::string_vie=
w is invalid soon after. The same thing can happen for c_str and data, but =
more obvious. From the SO question:</div><div><br></div><div>#include &lt;s=
tring&gt;</div><div>#include &lt;string_view&gt;</div><div>#include &lt;ios=
tream&gt;</div><div><br></div><div>std::string foo() {</div><div>=C2=A0 =C2=
=A0 return &quot;test&quot;;</div><div>}</div><div><br></div><div>int main(=
) {<br>=C2=A0 =C2=A0 std::string_view bar =3D foo(); // bar is pointed to d=
estructed string</div><div>=C2=A0 =C2=A0 std::cout &lt;&lt; bar &lt;&lt; st=
d::endl;</div><div>}</div><div><br></div><div>If the conversion operator wo=
uld have been marked with a &amp;, this would not have happened.</div></div=
></blockquote><div><br></div><div>And neither would this:</div><div><br></d=
iv><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(18=
7, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break-=
word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">void<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> some_func<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">string_view view</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br>some_func</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">());</span></div></code></div><div><br></div=
><div>Yet this is perfectly valid.<br></div><div><br></div><div>C++ has no =
good solution to this problem. You&#39;re either going to forbid legitimate=
 code, or allow broken code. We do not have any mechanism at present that a=
llows us to determine when such things are being used legitimately and when=
 they are not.</div><div><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/c3e093a8-05e2-4047-9079-c8356d7f12df%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c3e093a8-05e2-4047-9079-c8356d7f12df=
%40isocpp.org</a>.<br />

------=_Part_4723_1961309150.1510597517428--

------=_Part_4722_486267311.1510597517428--

.


Author: Nicolas Lesser <blitzrakete@gmail.com>
Date: Mon, 13 Nov 2017 19:29:00 +0100
Raw View
--001a113724ccc27c90055de17140
Content-Type: text/plain; charset="UTF-8"

True, I guess I didn't think it through properly. :)

--
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/CALmDwq1fFds9tTy67f6uct_zA9ECJKg2aQTP0yMjOoameAqAPQ%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra">True, I guess I didn&#39;t thin=
k it through properly. :)</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/CALmDwq1fFds9tTy67f6uct_zA9ECJKg2aQTP=
0yMjOoameAqAPQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALmDwq1fFds9tTy6=
7f6uct_zA9ECJKg2aQTP0yMjOoameAqAPQ%40mail.gmail.com</a>.<br />

--001a113724ccc27c90055de17140--

.