Rationale for cmath's std::abs(short) -> double
Stephan Bergmann
sbergman@redhat.com
Wed Feb 3 17:23:00 GMT 2016
On 02/03/2016 02:25 PM, Jonathan Wakely wrote:
> On 3 February 2016 at 10:57, Jonathan Wakely wrote:
>> abs is an oddity though, as it also has integral overloads. The
>> proposed resolution for http://wg21.link/lwg2192 suggests it should
>> promote to int, although it's not entirely clear.
>
> We could just remove the abs template, but then abs((__int128)0) and
> abs((__int<1>)0) would not compile.
>
> If we only had to support C++11 and later we could implement 2192
> pretty easily with common_type:
>
> #if __cplusplus >= 201103L
> // _GLIBCXX_RESOLVE_LIB_DEFECTS
> // 2192. Validity and return type of std::abs(0u) is unclear
> template<typename _Tp,
> typename _Integral = _Requires<is_integral<_Tp>>,
> typename _Promoted = typename common_type<int, _Tp>::type>
> constexpr _Promoted
> abs(_Tp __x)
> {
> static_assert(__or_<is_signed<_Tp>, is_same<int, _Promoted>>::value,
> "integral arguments to abs must be signed or promotable to int");
> return __x < 0 ? -__x : __x;
> }
> #endif
>
> This works for abs((short)0) and abs(unsigned short)0) and
> abs((__int128)0), but fails for abs(0u) and abs(0ul).
>
> I guess we also want abs((__float128)0) to work, without casting it to
> double, which would lose precision for large values. That fails today,
> and would still fail with the function template above, but we can add
> an overload for __float128.
>
> Is not supporting the __intN types in C++03 mode OK?
Thanks for the detailed reply; LWG 2192 is what I had apparently
forgotten about again.
(Personally, I'm probably even OK with the status quo---there's not too
many cases where that issue hits in practice (at least not in
LibreOffice), so sticking an explicit cast to int in isn't too much of a
pain when one is aware of that shortcoming in the current standard.)
More information about the Libstdc++
mailing list