{"id":1433,"date":"2015-02-01T07:32:20","date_gmt":"2015-01-31T21:32:20","guid":{"rendered":"http:\/\/brnz.org\/hbr\/?p=1433"},"modified":"2015-02-01T07:32:20","modified_gmt":"2015-01-31T21:32:20","slug":"what-is-1u","status":"publish","type":"post","link":"https:\/\/brnz.org\/hbr\/?p=1433","title":{"rendered":"What is -1u?"},"content":{"rendered":"<p>In C++, what exactly is <strong>-1u<\/strong>?<\/p>\n<p>It doesn&#8217;t seem like it should be difficult to answer &#8212; it&#8217;s only three characters: <strong>&#8211;<\/strong>, <strong>1<\/strong>, and <strong>u<\/strong>. And, knowing a little bit about C++, it seems like that&#8217;ll be <strong>(-1)<\/strong> negative one with that <strong>u<\/strong>\u00a0making <strong>((-1)u)<\/strong> an\u00a0<strong>unsigned int<\/strong>. Right?<\/p>\n<p>To be more specific, on an architecture where <strong>int<\/strong> is a 32 bit type, and negative numbers are represented using <a href=\"http:\/\/en.wikipedia.org\/wiki\/Two%27s_complement\">two&#8217;s complement<\/a> (i.e. just about all of them), negative one has the binary value 11111111111111111111111111111111. And converting that to <strong>unsigned int<\/strong> should &#8230; still be those same thirty two ones. Shouldn&#8217;t it?<\/p>\n<p>I can test that hypothesis! Here&#8217;s a program that will answer the question once and for all:<\/p>\n<pre escaped=\"true\" lang=\"c++\" line=\"1\">#include &lt;stdio.h&gt;\r\n#include &lt;type_traits&gt;\r\n\r\nint main()\r\n{\r\n static_assert(std::is_unsigned&lt;decltype(-1u)&gt;::value, \r\n               \"actually not unsigned\");\r\n printf(\"-1u is %zu bytes, with the value %#08x\\n \", \r\n        sizeof -1u, -1u);\r\n}\r\n<\/pre>\n<p><span style=\"line-height: 1.6471;\">Compile and run it like this:<\/span><\/p>\n<pre escaped=\"true\" lang=\"bash\">g++ -std=c++11 minus_one_u.cpp -o minus_one_u &amp;&amp; minus_one_u\r\n<\/pre>\n<p><span style=\"line-height: 1.6471;\">If I do that, I see the following output:<\/span><\/p>\n<pre escaped=\"true\" lang=\"text\">-1u is 4 bytes, with the value 0xffffffff<\/pre>\n<p>I&#8217;m using <strong>-std=c++11<\/strong> to be able to use\u00a0<strong>std::is_unsigned<\/strong>, <strong>decltype<\/strong> and <strong>static_assert<\/strong> which combine to assure me that <strong>(-1u)<\/strong> is actually unsigned as the program wouldn&#8217;t have compiled if that wasn&#8217;t the case.\u00a0And the output shows the\u00a0result I had hoped for: it&#8217;s a four byte value, containing\u00a0<strong>0xffffffff<\/strong> (which is the same as that string of thirty two ones I was looking for).<\/p>\n<p>I have now proven that <strong>-1u<\/strong> means &#8220;convert <strong>-1<\/strong>\u00a0to an <strong>unsigned int<\/strong>.&#8221;\u00a0Yay me!<\/p>\n<h3>Not so much.<\/h3>\n<p>It just so happened that I was reading about integer literals in a recent draft of the ISO C++ standard. Here&#8217;s the part of the standard that describes the format of decimal integer literals:<\/p>\n<blockquote><p>2.14.2 Integer literals<br \/>\n1 An <em>integer literal<\/em> is a sequence of digits that has no period or exponent part, with optional separating single\u00a0quotes that are ignored when determining its value. An integer literal may have a prefix that specifies\u00a0its base and a suffix that specifies its type. The lexically first digit of the sequence of digits is the most\u00a0significant. A <em>decimal<\/em> integer literal (base ten) begins with a digit other than 0 and consists of a sequence\u00a0of decimal digits.<\/p><\/blockquote>\n<p>Can you see where it describes negative integer literals?<\/p>\n<p>I can&#8217;t see where it describes negative integer literals.<\/p>\n<p>Oh.<\/p>\n<p>I though <b>-1u<\/b>\u00a0was <strong>((-1)u)<\/strong>.<strong>\u00a0<\/strong>I was wrong. Integer literals do not work that way.<\/p>\n<p>Obviously <strong>-1u<\/strong> didn&#8217;t just stop producing an <strong>unsigned int<\/strong> with the value <strong>0xffffffff <\/strong>(the program proved it!!1), but the reason it has that value is not the reason I thought.<\/p>\n<p>So, what is <strong>-1u<\/strong>?<\/p>\n<p>The standard says\u00a0that <b>1u<\/b>\u00a0is an integer literal. So now I need to work out exactly what that <strong>&#8211;<\/strong>\u00a0is doing. What does it mean to negate <strong>1u<\/strong>? Back to the standard I go.<\/p>\n<blockquote><p>5.3.1 Unary operators<br \/>\n8\u00a0The operand of the unary &#8211; operator shall have arithmetic or unscoped enumeration type and the result\u00a0is the negation of its operand. Integral promotion is performed on integral or enumeration operands. The\u00a0negative of an unsigned quantity is computed by subtracting its value from 2<em><sup>n<\/sup><\/em>, where <em>n<\/em> is the number of\u00a0bits in the promoted operand. The type of the result is the type of the promoted operand.<\/p><\/blockquote>\n<p>I feel like I&#8217;m getting closer to some real answers.<\/p>\n<p>So there&#8217;s a numerical operation to apply to this thing. But first, this:<\/p>\n<blockquote><p>Integral promotion is performed on integral or enumeration operands.<\/p><\/blockquote>\n<h3>Believe me when I tell you that this section changes nothing and you should skip it.<\/h3>\n<p>I have an integral operand (<strong>1u<\/strong>),\u00a0so integral promotion must be performed. Here is the part of the standard that deals with that:<\/p>\n<blockquote><p>4.5\u00a0Integral promotions<br \/>\n1 A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion\u00a0rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all\u00a0the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned\u00a0int.<\/p><\/blockquote>\n<p>I&#8217;m going to cut a corner here: integer literals\u00a0are prvalues, but I couldn&#8217;t find a place in the standard that explicitly declares this to be the case. It does seem pretty clear from 3.10 that they can&#8217;t be anything else. <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/value_category\">This page<\/a> gives a good rundown on C++ value categories, and does\u00a0state that integer literals are prvalues, so let&#8217;s go with that.<\/p>\n<p>If\u00a0<strong>1u<\/strong> is a prvalue, and its type is <strong>unsigned int<\/strong>, I can collapse the standard text a little:<\/p>\n<blockquote><p>4.5 Integral promotions (prvalue edition)<br \/>\nA value of an integer type whose integer conversion\u00a0rank (4.13) is less than the rank of int &#8230;<\/p><\/blockquote>\n<p>and I&#8217;m going to stop right there. Conversion rank what now? To 4.13!<\/p>\n<blockquote><p>4.13 Integer conversion rank<br \/>\n1 Every integer type has an <em>integer conversion rank<\/em> defined as follows:<\/p><\/blockquote>\n<p>Then a list of ten different rules, including this one:<\/p>\n<blockquote><p>\u2014 The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.<\/p><\/blockquote>\n<p>Without knowing more about conversion ranks, this rule gives me enough information to determine what 4.5 means for <strong>unsigned int<\/strong> values: <strong>unsigned int<\/strong>\u00a0has the same rank as\u00a0<strong>int<\/strong>.\u00a0So I can rewrite 4.5 one more time like this:<\/p>\n<blockquote><p>4.5\u00a0Integral promotions (unsigned int edition)<br \/>\n1\u00a0[This space intentionally left blank]<\/p><\/blockquote>\n<p>Integral promotion of an <strong>unsigned int<\/strong> value doesn&#8217;t change a thing.<\/p>\n<h3>Where was I?<\/h3>\n<p>Now I can rewrite 5.3.1 with the knowledge that <strong>1u<\/strong>\u00a0requires no integral promotion:<\/p>\n<blockquote><p>5.3.1 Unary operators (unsigned int operand edition)<br \/>\n8\u00a0The [result of] the unary &#8211; operator &#8230; is the negation of its operand. The\u00a0negative of an unsigned quantity is computed by subtracting its value from 2<em><sup>n<\/sup><\/em>, where <em>n<\/em> is the number of\u00a0bits in the promoted operand. The type of the result is the type of the operand.<\/p><\/blockquote>\n<p>And, at long last, I\u00a0get to do the negating. For an unsigned value that means:<\/p>\n<blockquote><p>[subtract] its value from 2<em><sup>n<\/sup><\/em>, where <em>n<\/em> is the number of\u00a0bits in the promoted operand.<\/p><\/blockquote>\n<p>My <strong>unsigned int<\/strong>\u00a0has 32 bits, so that would be <em>2<sup>32<\/sup>\u00a0&#8211; 1<\/em>. Which in hexadecimal looks something like this:<\/p>\n<pre escaped=\"true\" lang=\"text\">  0x100000000\r\n<span style=\"text-decoration: underline;\">- 0x000000001<\/span>\r\n  0x0ffffffff<\/pre>\n<p>But that leading zero I&#8217;ve left on the result goes away because<\/p>\n<blockquote><p>The type of the result is the type of the (promoted) operand.<\/p><\/blockquote>\n<p>And I am now certain that I know how\u00a0<strong>-1u<\/strong>\u00a0becomes an\u00a0<strong>unsigned int<\/strong> with the value <strong>0xffffffff<\/strong>. In fact, it&#8217;s not even dependent on having a platform that uses two&#8217;s complement \u00a0&#8212; nothing in the conversion relies on that.<\/p>\n<h3>But&#8230; when could this possibly ever matter?<\/h3>\n<p>For <strong>-1u<\/strong>?<strong>\u00a0<\/strong>I don&#8217;t see this ever causing actual problems. There are situations that arise from the way that C++ integer literals are defined that can cause surprises (i.e. bugs) for the unsuspecting programmer.<\/p>\n<p>There is a particular case described in the documentation for\u00a0<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/4kh09110.aspx\">Visual C++ compiler warning C4146<\/a>, but I think the rationale for that warning is wrong (or, at least, imprecise), but not because of something I&#8217;ve covered in this article. As I&#8217;ve already written far too many words about these three characters, I&#8217;ll keep that discussion\u00a0for some time in the future.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In C++, what exactly is -1u? It doesn&#8217;t seem like it should be difficult to answer &#8212; it&#8217;s only three characters: &#8211;, 1, and u. And, knowing a little bit about C++, it seems like that&#8217;ll be (-1) negative one with that u\u00a0making ((-1)u) an\u00a0unsigned int. Right? To be more specific, on an architecture where &hellip; <a href=\"https:\/\/brnz.org\/hbr\/?p=1433\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;What is -1u?&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,26],"tags":[],"_links":{"self":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1433"}],"collection":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1433"}],"version-history":[{"count":17,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1433\/revisions"}],"predecessor-version":[{"id":1450,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1433\/revisions\/1450"}],"wp:attachment":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1433"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1433"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1433"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}