Rationale for cmath's std::abs(short) -> double

Jonathan Wakely jwakely@redhat.com
Wed Feb 3 18:01:00 GMT 2016


On 03/02/16 18:23 +0100, Stephan Bergmann wrote:
>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?

We already have overloads for the __int<N> types, so we can just add
one for __float128, and maybe remove the function template entirely.
That will mean we have explicit overloads for all signed integer types
of equal or greater rank to int and for all floating point types.

Anything that can promote to int (such as short) will use abs(int).

Larger unsigned types will be ambiguous and so fail to compile (as
required by the proposed resolution of 2192).

I'll revisit this for GCC 7, after LWG 2192 is resolved (which should
happen in a month).



More information about the Libstdc++ mailing list