<div class="gmail_quote">On Sat, Feb 4, 2012 at 11:49 AM, Howard Hinnant <span dir="ltr"><<a href="mailto:hhinnant@apple.com">hhinnant@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Feb 4, 2012, at 2:29 PM, Eli Friedman wrote:<br>
> On Sat, Feb 4, 2012 at 10:50 AM, Howard Hinnant <<a href="mailto:hhinnant@apple.com">hhinnant@apple.com</a>> wrote:<br>
>> On Feb 4, 2012, at 1:19 PM, Howard Hinnant wrote:<br>
>><br>
>>> On Feb 4, 2012, at 1:16 PM, Sebastian Redl wrote:<br>
>>><br>
>>>><br>
>>>> On 04.02.2012, at 19:06, Howard Hinnant wrote:<br>
>>>><br>
>>>>> On Feb 4, 2012, at 12:52 PM, Howard Hinnant wrote:<br>
>>>>><br>
>>>>>> On Feb 4, 2012, at 12:04 PM, Eli Friedman wrote:<br>
>>>>>>><br>
>>>>>>> [expr.shift]p2: [...] if E1 has a signed type and non-negative value,<br>
>>>>>>> and E1×2E2 is representable in the result type, then that is the<br>
>>>>>>> resulting value; otherwise, the behavior is undefined.<br>
>>>>>>><br>
>>>>>>> -Eli<br>
>>>>>><br>
>>>>>> I see, you're point is that I've walked into undefined territory because I set the sign bit on the long long?  Does changing 1LL to 1ULL make the compiler happy?<br></div></div></blockquote>
<div><br></div><div>Yes, that should be fine.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
>>>>> Another question:  Is there a motivation for giving the compile time behavior of these operations a different behavior than they would have at run time?<br>
>>>><br>
>>>> The runtime behavior is undefined. Do you really want the compile time behavior to be the same?<br>
>>>><br>
>>>> As a side note, I think the diagnostics here could still be improved.<br></div></div></blockquote><div><br></div><div>I agree; wording suggestions would be appreciated.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">
>>>> Sebastian<br>
>>><br>
>>> It is undefined by the standards committee which has not had the willpower to abandon 1's complement hardware.  I believe it is well defined behavior on every platform we support (2's complement hardware).  I believe this compile time behavior is overly pedantic, does not reveal any programming error, and will only serve up busy work for clang's clients.<br>
</div></div></blockquote><div><br></div><div>I defer to your insight here, but I'd previously thought that the intention was to avoid signed integer overflow. If this is an integer representation issue, it's not clear to me why this isn't implementation-defined (like a right shift of a negative value is).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
>>><br>
>>> Howard<br>
>><br>
>> Just noticed:<br>
>><br>
>> On Feb 3, 2012, at 7:33 PM, Richard Smith wrote:<br>
>><br>
>>> constexpr:<br>
>>>  The recent support for potential constant expressions exposed a bug in the<br>
>>>  implementation of libstdc++4.6, where numeric_limits<int>::min() is defined<br>
>>>  as (int)1 << 31, which isn't a constant expression. Disable the 'constexpr<br>
>>>  function never produces a constant expression' error inside system headers<br>
>>>  to compensate.<br>
>><br>
>> So it appears already that this is an issue wider than just libc++.  And I would be surprised if the issue isn't wide spread.  Just did a quick search of Boost and found this:<br></div></div></blockquote><div>
<br></div><div>A bug has already been filed against libstdc++, and it appears they intend to fix it. It's not clear whether g++ will implement this check on left shifts.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">
>>      static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); }<br>
>><br>
>> Please reduce this to a pedantic warning and provide a way to turn it off locally even then.<br></div></div></blockquote><div><br></div><div>That is technically a little challenging; this is a note, not an error, and it's attached to probably over a dozen separate diagnostics. Plus, we'd need to somehow deal with the cases where an expression contains such a shift and also another subexpression which renders it non-constant. I'd much prefer to either keep the check or ditch it entirely -- I think we need to discuss this at Kona to choose which.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
> The problem is, this affects SFINAE...<br>
<br>
</div></div>You are much more familiar with Chapter 14 than I am.  However in all places I'm aware, if the standard says that something is undefined behavior, the implementation can do anything it wants.  It can cause toilets to explode.  Or it can simply do what it believes its customers wanted in the first place.  I believe this is a case where we should do the latter.<br>
</blockquote><div><br></div><div>The trouble is that this isn't undefined behavior -- the overflowing left shift makes the expression non-constant (because the result of multiplying by 2^N isn't a representable value of the type, or post-DR1313 because the expression would otherwise have undefined behavior), and if the expression is not evaluated (for instance, if it's part of a function type in a SFINAE context) then the program has a well-defined meaning. Let's make this a bit more concrete:</div>
<div><br></div><div>template<int n> auto f(int (&x)[n]) -> typename std::enable_if<(1 << n) < kMaxTableSize, int>::type {</div><div>  // ...</div><div><br></div><div>Here, if the 1<<n calculation overflows, the expression is non-constant and substitution fails.</div>
<div><br></div><div>- Richard</div></div>