abs vs std::abs, what does the reference say?

The official references say… it’s a mess. Pre-C++11 and C11:

  • Officially, including <cmath> introduced nothing in ::;
    all of the functions were in std::. Practically, only
    export was less respected, and different compilers did very
    different things. If you included <cmath>, you used std::
    everywhere, or what you got varied from compiler to compiler.

  • C didn’t provide any overloads: abs took an int, and was
    declared in <stdlib.h>, fabs took double, and was
    declared in <math.h>.

  • If you included <math.h> in C++, it’s not clear what you
    got, but since none of the implementers seemed to care about
    the standard anyway (see the first point above)…

Roughly speaking, either you included <cmath>, and prefixed
all of the uses with std::, or you included <math.h>, and
used fabs if you wanted support for floating point (and the
various suffixes for types other than int or double).

C++11 and C11 added a few new twists:

  • <cmath> is now allowed (but not required) to introduce the
    symbols in :: as well. One more thing which can vary
    depending on the implementation. (The goal here was to make
    existing implementations conformant.)

  • C has a new header, <tgmath.h>, which uses compiler magic to
    make the functions in <math.h> behave as if they were
    overloaded as in C++. (So it doesn’t apply to abs, but only
    to fabs.) This header had not been added to C++, for the
    obvious reason that C++ doesn’t need any compiler magic for
    this.

All in all, the situation has become slightly worse, and my
recommendations above still hold. Include either <math.h> and
<stdlib.h>, and use abs/fabs and their derivated (e.g.
labs, fabsf, etc.) exclusively, or include <cmath>, and
use std::abs exclusively. Anything else, and you’ll run into
portabiity problems.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)