Topic: Integral types to nullptr_t conversion


Author: =?UTF-8?Q?R=C3=B3bert_D=C3=A1vid?= <lrdxgm@gmail.com>
Date: Mon, 11 Mar 2013 17:26:27 -0700 (PDT)
Raw View
------=_Part_676_15040814.1363047987918
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hello!

Not-so-long time ago, I found something odd regarding nullptr_t. The=20
pattern of code I was improving/fixing/testing was something like:

std::shared_ptr<bool> doStuff()
{
  if(some_condition())
  {
    return false;   //Huh?
  }
  std::shared_ptr<bool> result;
  //  ...do stuff...
  return result;
}

The "return false" ended up there as a result of copy-paste, or the return=
=20
value was wrapped in the smart pointer later, I don't know, and isn't the=
=20
point. The point is, this whole thing compiles, and does something=20
unexpected. The first question everyone (including me, and my colleagues I=
=20
showed the code) asked: how do you convert a boolean to a shared_ptr (and=
=20
what will be the result)? Of course the answer is that you don't, as if you=
=20
change it to true, it is a compile error. If you change it to a=20
non-compile-time-const bool variable of false value, also compile error..

What happens here is that false gets converted to nullptr_t (with the value=
=20
of - not surprisingly - nullptr), and shared_ptr's constructor overload=20
with nullptr_t parameter gets called. Of course the resulting 'empty' smart=
=20
pointer isn't really what clients of the function want..

As the standard (at least, N3242) in section 4.10/1 tells:

> A null pointer constant is an integral constant expression (5.19) prvalue=
=20
> of integer type that evaluates to zero or a prvalue of type std::nullptr_=
t.=20
> (...) A null pointer constant of integral type can be converted to a=20
> prvalue of type std::nullptr_t.
>

OK, wait a minute. I can accept converting compile-time "0" to nullptr_t (
NULL macro case), but why bool, and even, why char(/char16_t/char32_t/
wchar_t)? To be honest, I would even forbid any conversion to nullptr_t -=
=20
use nullptr if you want one - or 0 or NULL, in case of old code.

Side note: I find 3.9.1/7 about defining integ*er* types to be the synonym=
=20
of integ*ral* types confusing: Integer (=3Dintegral) types this way include=
=20
singed integers, unsigned integers and a few other, "non-integer" types (bo=
ol,=20
char). I would define integer types as singed + unsigned integers, and=20
integral types as integer types + bool + char types... Also, seems like=20
char is included in signed integers, but mentioned again to include it to i=
ntegral=20
types. Side note end.

Here is a cleaned up list of conversions I talk about:
#include <memory>

class Foo { int x; };

std::shared_ptr<Foo> a1() { return false; } //No error!
std::shared_ptr<Foo> a2() { return true; }  //OK: Compile error

int __cdecl main(int, char**)
{
    std::nullptr_t a3 =3D false;  //No error!
    std::nullptr_t a4 =3D true;   //OK: Compile error

    const bool foo =3D false;
    std::nullptr_t a5 =3D foo;    //No error!

    const bool bar =3D true;
    std::nullptr_t a6 =3D bar;    //OK: Compile error

    bool meow =3D false;
    std::nullptr_t a7 =3D meow;   //OK: Compile error

    std::nullptr_t a8 =3D 0;      //OK: Same as using NULL macro
    std::nullptr_t a9 =3D 1234;   //OK: Compile error

    std::nullptr_t aA =3D '\0';   //No error!
    std::nullptr_t aB =3D '0';    //OK: Compile error
}

What I would like to see that all lines above (except for the NULL macro=20
related) to be actual errors. What do you guys think? *Can **the conversion=
=20
**to nullptr_t be restricted to from actual signed(/unsiged) integer=20
(instead of all integral) types?*

Regards, R=F3bert

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



------=_Part_676_15040814.1363047987918
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hello!<br><br>Not-so-long time ago, I found something odd regarding <span s=
tyle=3D"font-family: courier new,monospace;">nullptr_t</span>. The pattern =
of code I was improving/fixing/testing was something like:<br><br><div clas=
s=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: =
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">shared_ptr</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&lt;bool&gt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> doStuff</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>&nbsp; </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">if</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
some_condition</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">())</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>&nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; =
&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">false</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp; </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//Huh?</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>&nbsp; std</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">shared_ptr</span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">&lt;bool&gt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> result</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// &nbsp;...do stuff...</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> result</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span></div></code></div><br>The "<span style=3D"font-family:=
 courier new,monospace;">return false</span>"
 ended up there as a result of copy-paste, or the return value was=20
wrapped in the smart pointer later, I don't know, and isn't the point.=20
The point is, this whole thing compiles, and does something unexpected.=20
The first question everyone (including me, and my colleagues I showed=20
the code) asked: how do you convert a boolean to a <span style=3D"font-fami=
ly: courier new,monospace;">shared_ptr</span> (and what will be the result)=
? Of course the answer is that you don't, as if you change it to <span styl=
e=3D"font-family: courier new,monospace;">true</span>, it is a compile erro=
r. If you change it to a non-compile-time-const bool variable of false valu=
e, also compile error..<br><br>What happens here is that <span style=3D"fon=
t-family: courier new,monospace;">false</span> gets converted to <span styl=
e=3D"font-family: courier new,monospace;">nullptr_t</span> (with the value =
of - not surprisingly - <span style=3D"font-family: courier new,monospace;"=
>nullptr</span>), and <span style=3D"font-family: courier new,monospace;">s=
hared_ptr</span>'s constructor overload with <span style=3D"font-family: co=
urier new,monospace;">nullptr_t</span> parameter gets called. Of course the=
 resulting 'empty' smart pointer isn't really what clients of the function =
want..<br><br>As the standard (at least, N3242) in section 4.10/1 tells:<br=
><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb=
(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">A
 null pointer constant is an integral constant expression (5.19) prvalue
 of integer type that evaluates to zero or a prvalue of type=20
std::nullptr_t. (...) A null pointer constant of integral type can be=20
converted to a prvalue of type std::nullptr_t.<br></blockquote><br>OK, wait=
 a minute. I can accept converting compile-time "<span style=3D"font-family=
: courier new,monospace;">0</span>" to <span style=3D"font-family: courier =
new,monospace;">nullptr_t</span> (<span style=3D"font-family: courier new,m=
onospace;">NULL</span> macro case), but why <span style=3D"font-family: cou=
rier new,monospace;">bool</span>, and even, why <span style=3D"font-family:=
 courier new,monospace;">char</span>(/<span style=3D"font-family: courier n=
ew,monospace;">char16_t</span>/<span style=3D"font-family: courier new,mono=
space;">char32_t</span>/<span style=3D"font-family: courier new,monospace;"=
>wchar_t</span>)? To be honest, I would even forbid any conversion to <span=
 style=3D"font-family: courier new,monospace;">nullptr_t</span> - use <span=
 style=3D"font-family: courier new,monospace;">nullptr</span> if you want o=
ne - or <span style=3D"font-family: courier new,monospace;">0</span> or <sp=
an style=3D"font-family: courier new,monospace;">NULL</span>, in case of ol=
d code.<br><br><font size=3D"1">Side note: I find 3.9.1/7 about defining in=
teg<u><b>er</b></u> types to be the s<font size=3D"1">yno<font size=3D"1">n=
ym of integ<u><b>ral</b></u> </font></font>t<font size=3D"1">ypes </font>co=
nfusing: Integer (<font size=3D"1">=3Dintegral<font size=3D"1">)</font></fo=
nt> <font size=3D"1">types this <font size=3D"1">way </font><font size=3D"1=
">include singed<font size=3D"1"> <font size=3D"1"><font size=3D"1"><font s=
ize=3D"1">integers</font>, unsi<font size=3D"1">gned integers and <font siz=
e=3D"1">a few other, <font size=3D"1"><font size=3D"1">"</font>non-integer"=
 types <font size=3D"1">(bool, char<font size=3D"1">).&nbsp;</font></font><=
/font></font></font></font></font></font></font></font></font><font size=3D=
"1"><font size=3D"1">I would define integer types as singed + unsigned inte=
gers, and integral types as integer types + bool + char types... </font></f=
ont><font size=3D"1"><font size=3D"1"><font size=3D"1">Also, seems like cha=
r is included in signed integers<font size=3D"1">, <font size=3D"1">but men=
tioned <font size=3D"1">again to include it to in<font size=3D"1">tegral t<=
font size=3D"1">ypes. </font></font></font></font></font></font></font></fo=
nt><font size=3D"1">Side note end.</font><br><br>Here is a cleaned up list =
of conversions I talk about:<br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"=
styled-by-prettify">#include</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-p=
rettify">&lt;memory&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan 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=
: #008;" class=3D"styled-by-prettify">int</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"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r><br>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">shared_pt=
r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a1</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">false</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </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">//No error!</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">shared_ptr</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-=
by-prettify">Foo</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 a2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">true</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp;</span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">//OK: Compile er=
ror</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> __cdecl main</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">int</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: #008;" =
class=3D"styled-by-prettify">char</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">**)</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>&nbsp; &nbsp; std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">nullptr_t a3 </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">false</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp;</span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">//No error!</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">nullptr_t a4 </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">true</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> &nbsp; </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">//OK: Compile error</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br><br>&nbsp; &nbsp; </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> foo </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">false</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; &nbsp; std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">nul=
lptr_t a5 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp; &nbsp;</span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">//No error!</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; &n=
bsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> bar </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>&nbsp; &nbsp; std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">nullptr_t a6 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> bar</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> &nbsp; &nbsp;</span><span style=3D"color: #800;" class=3D"styled-by-pret=
tify">//OK: Compile error</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> meow </span><span style=3D"color: #660;" class=3D"sty=
led-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"=
>false</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &n=
bsp; std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">nullptr_t =
a7 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> meow</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp; </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//OK: Compile error</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; &nbs=
p; std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">nullptr_t a8=
 </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 st=
yle=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> &nbsp; &nbsp; &nbsp;</span><span style=3D"=
color: #800;" class=3D"styled-by-prettify">//OK: Same as using NULL macro</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &=
nbsp; std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">nullptr_t=
 a9 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #066;" class=3D"styled-by-prettify">1234</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> &nbsp; </span><span style=3D"color: =
#800;" class=3D"styled-by-prettify">//OK: Compile error</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; &nbsp; std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">nullptr_t aA </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">'\0'</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> &nbsp; </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">//No error!</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>&nbsp; &nbsp; std</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">nullptr_t aB</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </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: #080;" class=3D"styled-by-prett=
ify">'0'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp; &nb=
sp;</span><span style=3D"color: #800;" class=3D"styled-by-prettify">//OK: C=
ompile error</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></=
div></code></div><br>What I would like to see that all lines above (except =
for the NULL macro related) to be actual errors. What
 do you guys think? <u>Can </u><u><u>the conversion </u></u><u><u><u>to nul=
lptr_t </u></u>be restricted to from actual=20
signed(/unsiged) integer (instead of all integral) types?</u><br><br>Regard=
s, R=F3bert

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_676_15040814.1363047987918--

.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Tue, 12 Mar 2013 08:08:33 +0100
Raw View
2013/3/12 R=F3bert D=E1vid <lrdxgm@gmail.com>:
> Hello!
>
> Not-so-long time ago, I found something odd regarding nullptr_t. The patt=
ern
> of code I was improving/fixing/testing was something like:
>
> std::shared_ptr<bool> doStuff()
> {
>   if(some_condition())
>   {
>     return false;   //Huh?
>   }
>   std::shared_ptr<bool> result;
>   //  ...do stuff...
>   return result;
> }
>
> The "return false" ended up there as a result of copy-paste, or the retur=
n
> value was wrapped in the smart pointer later, I don't know, and isn't the
> point. The point is, this whole thing compiles, and does something
> unexpected. The first question everyone (including me, and my colleagues =
I
> showed the code) asked: how do you convert a boolean to a shared_ptr (and
> what will be the result)? Of course the answer is that you don't, as if y=
ou
> change it to true, it is a compile error. If you change it to a
> non-compile-time-const bool variable of false value, also compile error..
>
> What happens here is that false gets converted to nullptr_t (with the val=
ue
> of - not surprisingly - nullptr), and shared_ptr's constructor overload w=
ith
> nullptr_t parameter gets called. Of course the resulting 'empty' smart
> pointer isn't really what clients of the function want..
>
> As the standard (at least, N3242) in section 4.10/1 tells:
>>
>> A null pointer constant is an integral constant expression (5.19) prvalu=
e
>> of integer type that evaluates to zero or a prvalue of type std::nullptr=
_t.
>> (...) A null pointer constant of integral type can be converted to a prv=
alue
>> of type std::nullptr_t.
>
>
> OK, wait a minute. I can accept converting compile-time "0" to nullptr_t
> (NULL macro case), but why bool, and even, why
> char(/char16_t/char32_t/wchar_t)? To be honest, I would even forbid any
> conversion to nullptr_t - use nullptr if you want one - or 0 or NULL, in
> case of old code.
>
> Side note: I find 3.9.1/7 about defining integer types to be the synonym =
of
> integral types confusing: Integer (=3Dintegral) types this way include si=
nged
> integers, unsigned integers and a few other, "non-integer" types (bool,
> char). I would define integer types as singed + unsigned integers, and
> integral types as integer types + bool + char types... Also, seems like c=
har
> is included in signed integers, but mentioned again to include it to
> integral types. Side note end.
>
> Here is a cleaned up list of conversions I talk about:
> #include <memory>
>
> class Foo { int x; };
>
> std::shared_ptr<Foo> a1() { return false; } //No error!
> std::shared_ptr<Foo> a2() { return true; }  //OK: Compile error
>
> int __cdecl main(int, char**)
> {
>     std::nullptr_t a3 =3D false;  //No error!
>     std::nullptr_t a4 =3D true;   //OK: Compile error
>
>     const bool foo =3D false;
>     std::nullptr_t a5 =3D foo;    //No error!
>
>     const bool bar =3D true;
>     std::nullptr_t a6 =3D bar;    //OK: Compile error
>
>     bool meow =3D false;
>     std::nullptr_t a7 =3D meow;   //OK: Compile error
>
>     std::nullptr_t a8 =3D 0;      //OK: Same as using NULL macro
>     std::nullptr_t a9 =3D 1234;   //OK: Compile error
>
>     std::nullptr_t aA =3D '\0';   //No error!
>     std::nullptr_t aB =3D '0';    //OK: Compile error
> }
>
> What I would like to see that all lines above (except for the NULL macro
> related) to be actual errors. What do you guys think? Can the conversion =
to
> nullptr_t be restricted to from actual signed(/unsiged) integer (instead =
of
> all integral) types?

Yes, they can, see

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903

But your example points out a conflict here, if you look at the very
last comment to that issue state:

"Concerns were raised at the Portland (October, 2012) meeting that the
value false has been used in existing code as a null pointer constant,
and such code would be broken by this change. This issue has been
returned to "review" status to allow discussion of whether to
accommodate such code or not."

- Daniel

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



.


Author: Johannes Schaub <schaub.johannes@googlemail.com>
Date: Tue, 12 Mar 2013 03:15:00 -0700 (PDT)
Raw View
The code you show currently is not valid. See issue http://www.open-std.org=
/jtc1/sc22/wg21/docs/cwg_closed.html#1448 . The conversion of false to a po=
inter type cannot be done by a single implicit conversion sequence because =
it requires both an integral conversion or promotion and a pointer conversi=
on in a row.


Original Message replied to:

Hello!

Not-so-long time ago, I found something odd regardingnullptr_t. The pattern=
 of code I was improving/fixing/testing was something like:

std::shared_ptr<bool> doStuff() { if(some_condition()) { return false;

} std::shared_ptr<bool> result; // ...do stuff... return result; }

The "return false" ended up there as a result of copy-paste, or the return =
value was wrapped in the smart pointer later, I don't know, and isn't the p=
oint. The point is, this whole thing compiles, and does something unexpecte=
d. The first question everyone (including me, and my colleagues I showed th=
e code) asked: how do you convert a boolean to ashared_ptr (and what will b=
e the result)? Of course the answer is that you don't, as if you change it =
totrue, it is a compile error. If you change it to a non-compile-time-const=
 bool variable of false value, also compile error..

What happens here is thatfalse gets converted tonullptr_t (with the value o=
f - not surprisingly -nullptr), andshared_ptr's constructor overload withnu=
llptr_t parameter gets called. Of course the resulting 'empty' smart pointe=
r isn't really what clients of the function want..

As the standard (at least, N3242) in section 4.10/1 tells: A null pointer c=
onstant is an integral constant expression (5.19) prvalue of integer type t=
hat evaluates to zero or a prvalue of type std::nullptr_t. (...) A null poi=
nter constant of integral type can be converted to a prvalue of type std::n=
ullptr_t.

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Tue, 12 Mar 2013 13:38:45 +0100
Raw View
2013/3/12 Johannes Schaub <schaub.johannes@googlemail.com>:
> The code you show currently is not valid. See issue http://www.open-std.o=
rg/jtc1/sc22/wg21/docs/cwg_closed.html#1448 . The conversion of false to a =
pointer type cannot be done by a single implicit conversion sequence becaus=
e it requires both an integral conversion or promotion and a pointer conver=
sion in a row.
>

Are you sure? Let's ignore CWG 903 for the moment (my understanding is
that 1448 was declared NAD because of CWG 903 but this one is in
review phase): My reading of 4.10 p1 is that there is only a single
conversion sequence:

"A null pointer constant of integral type can be converted to a
prvalue of type std::nullptr_t."

Note that std::shared_ptr has the following constructor:

constexpr shared_ptr(nullptr_t);

Unless I have misunderstood something completely, the example provided
by R=F3bert should be valid in the absence of CWG 903.

- Daniel

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



.


Author: =?UTF-8?Q?R=C3=B3bert_D=C3=A1vid?= <lrdxgm@gmail.com>
Date: Tue, 12 Mar 2013 08:30:05 -0700 (PDT)
Raw View
------=_Part_392_30507898.1363102205925
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



2013. m=E1rcius 12., kedd 11:15:00 UTC+1 id=F5pontban Johannes Schaub a=20
k=F6vetkez=F5t =EDrta:
>
> The code you show currently is not valid. See issue=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1448 . The=20
> conversion of false to a pointer type cannot be done by a single implicit=
=20
> conversion sequence because it requires both an integral conversion or=20
> promotion and a pointer conversion in a row.


bool is an integral type (according to 3.9.1/7), thus both false and truear=
e integral constant expressions of integral type (as per 5.19, no=20
surprise so far), so wichever evaluates to zero is a null pointer constant=
=20
(as per 4.10/1). The standard only states that false only *converts* to 0=
=20
(and true to 1), it does not tell what it *evaluates* to (same problem as=
=20
in CWG 1448). Ad absurdum in C++11 it it allowed for an implementation to=
=20
evaluate true to 0 and false to 42 (just make sure it is converted to=20
another integral type correctly), effectively making true the null pointer=
=20
constant, what is nonsense.

In C++11 it is an issue, that was the base of my question. CWG 1448 is=20
closed as NAD telling the resolution of another, but still open issue (CWG=
=20
903) will solve it, so I would not say it is solved.

Regards, R=F3bert

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



------=_Part_392_30507898.1363102205925
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>2013. m=E1rcius 12., kedd 11:15:00 UTC+1 id=F5pontban Johannes Scha=
ub a k=F6vetkez=F5t =EDrta:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The=
 code you show currently is not valid. See issue <a href=3D"http://www.open=
-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1448" target=3D"_blank">http:/=
/www.open-std.org/jtc1/<wbr>sc22/wg21/docs/cwg_closed.<wbr>html#1448</a> . =
The conversion of false to a pointer type cannot be done by a single implic=
it conversion sequence because it requires both an integral conversion or p=
romotion and a pointer conversion in a row.</blockquote><div><br><span styl=
e=3D"font-family: courier new,monospace;">bool</span> is an integral type (=
according to 3.9.1/7), thus both <span style=3D"font-family: courier new,mo=
nospace;">false</span> and <span style=3D"font-family: courier new,monospac=
e;">true</span> are integral constant expressions of integral type (as per =
5.19, no surprise so far), so wichever evaluates to zero is a null pointer =
constant (as per 4.10/1). The standard only states that false only <u>conve=
rts</u> to 0 (and true to 1), it does not tell what it <u>evaluates</u> to =
(same problem as in CWG 1448). Ad absurdum in C++11 it it allowed for an im=
plementation to evaluate true to 0 and false to 42 (just make sure it is co=
nverted to another integral type correctly), effectively making true the nu=
ll pointer constant, what is nonsense.<br><br>In C++11 it is an issue, that=
 was the base of my question. CWG 1448 is closed as NAD telling the resolut=
ion of another, but still open issue (CWG 903) will solve it, so I would no=
t say it is solved.<br><br>Regards, R=F3bert<br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_392_30507898.1363102205925--

.


Author: Johannes Schaub <schaub.johannes@googlemail.com>
Date: Wed, 13 Mar 2013 03:37:13 -0700 (PDT)
Raw View
The Standard is very clear. It says at 3.9.1p6 that *values* of type bool a=
re either true or false (note that this should be thought of as distinct fr=
om the keywords. here we have values, and the keywords are expressions when=
 they are used. the values true and false "coincidentally" are the result o=
f evaluating the expressions true and false respectively. they are like ato=
ms and stand for themselfs without a deeper external meaning).

It does nowhere say that false is an alternative phrase for the value zero.=
 So false and true are two integral values that cannot be represented by no=
nbool integral types, and vice versa zero and one and the other numbers can=
t be represented by bool as by 3.9.1p6.

What evaluation means is defined by 1.9p12 and is simply getting a value or=
 entity identity. The type of boolean literals is bool and thus their value=
 cannot be zero.

Note that this following snippet is illformed as well:

    bool x =3D true;
    int a =3D { x }; // narrowing



Original message replied to:=20

2013. m=E1rcius 12., kedd 11:15:00 UTC+1 id=F5pontban Johannes Schaub a k=
=F6vetkez=F5t =EDrta: The code you show currently is not valid. See issue h=
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1448 . The conve=
rsion of false to a pointer type cannot be done by a single implicit conver=
sion sequence because it requires both an integral conversion or promotion =
and a pointer conversion in a row.

bool is an integral type (according to 3.9.1/7), thus bothfalse andtrue are=
 integral constant expressions of integral type (as per 5.19, no surprise s=
o far), so wichever evaluates to zero is a null pointer constant (as per 4.=
10/1). The standard only states that false only converts to 0 (and true to =
1), it does not tell what it evaluates to (same problem as in CWG 1448). Ad=
 absurdum in C++11 it it allowed for an implementation to evaluate true to =
0 and false to 42 (just make sure it is converted to another integral type =
correctly), effectively making true the null pointer constant, what is nons=
ense.

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



.