<div class="gmail_quote">On Tue, Jan 31, 2012 at 12:40 AM, Abramo Bagnara <span dir="ltr"><<a href="mailto:abramo.bagnara@gmail.com">abramo.bagnara@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Il 31/01/2012 03:22, Eli Friedman ha scritto:<br>
<div><div class="h5">> On Mon, Jan 30, 2012 at 6:01 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
>> On Mon, Jan 30, 2012 at 4:29 PM, Eli Friedman <<a href="mailto:eli.friedman@gmail.com">eli.friedman@gmail.com</a>><br>
>> wrote:<br>
>>><br>
>>> On Mon, Jan 30, 2012 at 2:27 PM, Richard Smith<br>
>>> <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
>>>> Author: rsmith<br>
>>>> Date: Mon Jan 30 16:27:01 2012<br>
>>>> New Revision: 149286<br>
>>>><br>
>>>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=149286&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=149286&view=rev</a><br>
>>>> Log:<br>
>>>> constexpr: disallow signed integer overflow in integral conversions in<br>
>>>> constant<br>
>>>> expressions in C++11.<br>
>>><br>
>>> Standard citation?  As far as I can tell, the result of<br>
>>> (int)0x80000000u is implementation-defined, but it's still a constant<br>
>>> expression given how we define it.<br>
>><br>
>><br>
>> Oops, r149327. This was (incorrectly) factored out of another change which<br>
>> I'm still questioning... Consider:<br>
>><br>
>>   enum E { n = 2 };<br>
>>   E e = (E)5;<br>
>><br>
>> 5 is not in the range of values of the enumeration (which is 0..3 by<br>
>> [dcl.enum]p7), but is clearly in the underlying type. Is this value in the<br>
>> range of representable values for its type (or is this undefined behavior by<br>
>> [expr]p4)?<br>
><br>
> I think the relevant passage is actually [expr.static.cast]p10:<br>
><br>
> A value of integral or enumeration type can be explicitly converted to<br>
> an enumeration type. The value is unchanged if the original value is<br>
> within the range of the enumeration values (7.2). Otherwise, the<br>
> resulting value is unspecified (and might not be in that range).<br>
><br>
><br>
> That doesn't sound like undefined behavior to me.<br>
<br>
</div></div>Yes, you're definitely right from a standard point of view, but using<br>
the point of view of constant evaluator, does it make a difference?<br>
<br>
I.e., the conversion of an integer out of enum range specified by<br>
[decl.enum]p7 to that enum type should be a known constant?<br>
<br>
I don't think so, but I'd like to hear your opinion.</blockquote><div> </div><div>In C++11, all conditional-expressions are core constant expressions, except those explicitly blacklisted in [expr.const]p2. The only relevant exemption there is "a result that is not mathematically defined or not in the range of representable values for its type;" (which DR1313 generalizes to "an operation that would have undefined behavior").</div>
<div><br></div><div>The standard does not make obvious what it means by "the range of representable values" for an enumeration type. Is it the range of values of the enumeration, or is it the range of representable values of the underlying type, or something else? And, when casting an out-of-range value to an enumeration, can the resulting unspecified value be out of the range of representable values for the type?</div>
<div><br></div><div><div>To address the first question, [class.bit]p4 says:</div><div><br></div><div>"If the value of an enumerator is stored into a bit-field of the same enumeration type and the number of bits in the bit-field is large enough to hold all the values of that enumeration type (7.2), the original enumerator value and the value of the bit-field shall compare equal."</div>
<div><br></div><div>From this, and the behavior of integral promotions on enumerations, I believe we can conclude that the range of representable values of an enumeration type is the range of values of the enumeration.</div>
</div><div><br></div><div>Eli's quotation states that casting an out-of-range value to an enumeration produces a value which need not be in the range of values of the enumeration. Therefore, if the unspecified value is not in that range (which by [expr.static.cast]p10 it might not be), then behavior is undefined, and the result of the cast is not a constant expression.</div>
<div><br></div><div>That said, such deductive reasoning applied to the (sadly, often imprecise and inconsistent) standard wording has led me to unintended conclusions several times before, so I'm still not certain whether such cases should be constant expressions.</div>
<div><br></div><div>- Richard</div></div>