[cfe-commits] libc++ and const expr.

Howard Hinnant hhinnant at apple.com
Sat Feb 4 10:06:50 PST 2012


On Feb 4, 2012, at 12:52 PM, Howard Hinnant wrote:

> On Feb 4, 2012, at 12:04 PM, Eli Friedman wrote:
> 
>> On Sat, Feb 4, 2012 at 8:53 AM, Howard Hinnant <hhinnant at apple.com> wrote:
>>> On Feb 4, 2012, at 5:25 AM, Jean-Daniel Dupas wrote:
>>> 
>>>> Hi,
>>>> 
>>>> Am I the only one having trouble compiling libc++ with clang TOT.
>>>> For sometime now, clang refuse to compile (and use it) because of the following issue:
>>>> 
>>>> ../include/ratio:193:19: error: static_assert expression is not an integral constant expression
>>>>    static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, "overflow in __ll_mul");
>>>>                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> ../include/ratio:308:13: note: in instantiation of template class 'std::__1::__ll_mul<1, 1>' requested here
>>>>            __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
>>>>            ^
>>>> ../include/ratio:315:33: note: in instantiation of template class 'std::__1::__ratio_divide<std::__1::ratio<1, 1000000000>, std::__1::ratio<1, 1000000000> >' requested
>>>>      here
>>>> template <class _R1, class _R2> using ratio_divide
>>>>                                ^
>>>> ../include/chrono:410:18: note: in instantiation of template type alias 'ratio_divide' requested here
>>>>                (ratio_divide<_Period2, period>::type::den == 1 &&
>>>>                 ^
>>>> ../include/chrono:406:9: note: while substituting deduced template arguments into function template 'duration' [with _Rep2 = long long, _Period2 = <no value>]
>>>>        duration(const duration<_Rep2, _Period2>& __d,
>>>>        ^
>>>> ../include/ratio:193:26: note: initializer of 'nan' is not a constant expression
>>>>    static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, "overflow in __ll_mul");
>>>>                         ^
>>>> ../include/ratio:187:27: note: declared here
>>>>    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
>>>>                          ^
>>>> ../include/ratio:187:27: note: declared here
>>>> ../include/ratio:189:27: note: declared here
>>>>    static const intmax_t max = -min;
>>> 
>>> I haven't noticed because I'm not using TOT clang, and I've been distracted by libc++abi for the past couple of months.
>>> 
>>> But I note the crux of this issue appears to be that this:
>>> 
>>>  static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
>>> 
>>> is no longer consider a compile time constant expression.
>>> 
>>> This is one of two things:
>>> 
>>> 1.  A clang bug.
>>> 2.  A standards defect.  I.e. this will break a lot of C++03 code if the standard really says this.
>>> 
>>> If it is 2) it would be good for me to know immediately.  The next C++ standards meeting is next week (Feb. 6-10) and it would be good to give such a defect a high profile/priority at the meeting.
>>> 
>>> Does anyone know if this is 1) or 2)?
>> 
>> [expr.shift]p2: [...] if E1 has a signed type and non-negative value,
>> and E1×2E2 is representable in the result type, then that is the
>> resulting value; otherwise, the behavior is undefined.
>> 
>> -Eli
> 
> 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?

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?

Howard





More information about the cfe-commits mailing list