<div dir="ltr">On Fri, Oct 25, 2013 at 5:57 PM, Lawrence Crowl <span dir="ltr"><<a href="mailto:Lawrence@crowl.org" target="_blank">Lawrence@crowl.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 10/25/13, Richard Smith <<a href="mailto:richardsmith@google.com">richardsmith@google.com</a>> wrote:<br>
> On Oct 25, 2013, Gabriel Dos Reis <<a href="mailto:gdr@axiomatics.org">gdr@axiomatics.org</a>>wrote:<br>
> > Matt Austern <<a href="mailto:austern@google.com">austern@google.com</a>> writes:<br>
<div><div class="h5">> > > On Oct 25, 2013, Jeffrey Yasskin <<a href="mailto:jyasskin@google.com">jyasskin@google.com</a>> wrote:<br>
> > > > Richard explicitly asked whether any such C++ users exist or<br>
> > > > are likely to exist in the future, and nobody's come up with<br>
> > > > any examples. So we appear to have a choice between helping<br>
> > > > some theoretical people or helping some actual people. (We<br>
> > > > help the actual people by telling them what to expect in the<br>
> > > > standard, while now they have to test and hope they find the<br>
> > > > right subset of undefined or implementation-defined behavior<br>
> > > > that's actually guaranteed to work.)<br>
> > ><br>
> > > It's actually a little worse than that. Testing can reveal<br>
> > > what your implementation does today, with your particular<br>
> > > input, with one set of compiler flags. No amount of testing<br>
> > > can reveal what guarantees your implementation makes.<br>
> ><br>
> > There are two separate issues here:<br>
> ><br>
> > (1) whether we want C++ to continue to support non-two's<br>
> > complement binary representation<br>
> > (2) what we want to say about overflowing shift arithmetic<br>
> ><br>
> > Requirint two's complement does not necessarily solve (2). And<br>
> > solving (2) does not necessarily imply "no" to (1).<br>
><br>
> Agreed. It would definitely be interesting to complete Jeffrey's<br>
> list of the things we could define if we standardized 2s<br>
> complement, and then investigate how many of these we are<br>
> comfortable defining without specifying 2s complement. So far, we<br>
> have:<br>
><br>
> 1) overflowing unsigned->signed conversions<br>
> 2) right-shifts on negative operands<br>
> 3) bitwise operators<br>
><br>
> Are there others?<br>
<br>
</div></div>While we are on this topic, we should list that defining a<br>
two's complement representation will exclude using 1000... as<br>
a trap value. I think that is the right decision once you have<br>
bitwise operators, because -1^INT_MAX yields the bit pattern.<br>
<div class="im"><br>
> (1) and (2) are currently implementation-defined;<br>
<br>
</div>(1) is almost always the inverse of signed->unsigned conversion.<br>
However, I am not excited about either. I want a run-time<br>
diagnosis when I convert a negative number to unsigned or when<br>
I overflow a signed number when converting from unsigned. This<br>
diagnosis could happen from a new conversion operator, e.g.<br>
checked_cast<unsigned int>(-3).<br>
<div class="im"><br>
> (3) seems underspecified in the current standard.<br>
<br>
</div>I have yet to use a machine in which s>>n was not implemented<br>
as floor(s/pow(2,n)), but then I've been using two's complement<br>
machines.<br>
<div class="im"><br>
> [I think for consistency we should at least make (3) say that<br>
> bitwise operators on positive operands act as "expected" (that<br>
> is, they give the result that a 2s complement, 1s complement<br>
> or sign-magnitude machine would), and we should make these<br>
> operations on other machines implementation-defined.<br>
<br>
</div>I think we need a definition more specific than "expected". :)</blockquote><div><br></div><div>The purpose of my "that is..." parenthetical was to informally define what I meant by "expected" =)</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im HOEnZb">
> More generally, we should at least say that each integral type<br>
> must be one of 1s complement, 2s complement or sign-magnitude.<br>
> C currently requires this (C99/C11 <a href="http://6.2.6.2/2" target="_blank">6.2.6.2/2</a>), but C++ does not<br>
> (3.9.1/7's list of representations is not normative and not<br>
> restrictive). 7.2/8 implies that we don't support other<br>
> representations, but there's no normative justification for this<br>
> assumption.]<br>
><br>
> If we require that either (1) or (3) acts as-if 2s complement,<br>
> that actually rules out 1s complement and sign-magnitude<br>
> representations, because these expressions compute a value that<br>
> does not exist in the other representations <a href="tel:%28-2147483648" value="+12147483648">(-2147483648</a> for a<br>
> 32-bit integer):<br>
><br>
> int(unsigned(INT_MAX) + 1) // for (1)<br>
> int(-1 ^ INT_MAX) // for (3)<br>
><br>
> We could define that (2) acts as-if 2s complement (divide by 2^N<br>
> and round down). I think that's the least valuable operation to<br>
> define of the three, though.<br>
<br>
</div><span class="HOEnZb"><font color="#888888">--<br>
Lawrence Crowl<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
ub mailing list<br>
<a href="mailto:ub@isocpp.open-std.org">ub@isocpp.open-std.org</a><br>
<a href="http://www.open-std.org/mailman/listinfo/ub" target="_blank">http://www.open-std.org/mailman/listinfo/ub</a><br>
</div></div></blockquote></div><br></div></div>