[Bug libstdc++/54686] New: std::abs (long long) resorts to std::abs (double) if llabs is absent

olegendo at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Sep 23 20:21:00 GMT 2012


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54686

             Bug #: 54686
           Summary: std::abs (long long) resorts to std::abs (double) if
                    llabs is absent
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: olegendo@gcc.gnu.org


I'm not sure, whether this is intentional or not, but on my SH xgcc setup with
newlib 1.20.0 the following:

#include <cstddef>
#include <cstdint>
#include <algorithm>

int64_t test (int64_t* b)
{
  return std::abs (*b);
}

ends up doing an abs of a double.
Looking at the preprocessed source, the following looks suspicious:

  template<typename _Tp>
    inline constexpr
    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                    double>::__type
    abs(_Tp __x)
    { return __builtin_fabs(__x); }

I guess since there's no overload for long long due to the lack of llabs, the
template function above is taken instead.  However, this can't be right and
won't actually work for large 64 bit int numbers.
Although probably the proper fix would be to add llabs to newlib, I think the
enable_if above should also check whether the integer has any chance of fitting
into the double.



More information about the Gcc-bugs mailing list