I've come across a few different examples of ways in which std::abs
can give unexpected results:
<cstdlib>
provides overloads for integral types while <cmath>
provides overloads for floating point types. Failing to include the correct header gives undefined behaviour, which the compiler is allowed to silently acceptstd::abs(short)
returns a double
, although most compilers ignore the relevant wording and return an int
. The resolution to this issue indicates that the wording was changed in C++17 so that std::abs(short)
returns an int
std::abs
can lead to difficult-to-spot bugs, since (in modern C++) the headers which introduce std::abs
are allowed to introduce a global abs
function (which may or may not have the same overloads), and it's easy to accidentally use abs
instead of std::abs
The fixes that I am aware of are:
<cstdlib>
if evaluating std::abs([integral type])
and <cmath>
if evaluating std::abs([floating point type])
std::abs(short)
may return an int
or a double
depending on the compiler's compliance with the C++11/C++14 standard–Wconversion
so that calls like abs(2.0)
trigger a warning at compilationabs
ambiguousTrick:
namespace neveruse{
int abs(int);
}
using namespace neveruse;
Question: Is there a reason to prefer one of the solutions to issue 3 over the other? Do any of these fixes introduce other potential problems that I need to watch out for?
Create a header file of your own that defines an inline
functionabsolute
that in turn includes all the correct headers and fixes bugs with return types, and calls std::abs
.
Then, don't use abs
or std::abs
(or any token named abs
). Enforce this at git commit (or whatever version management system you are using) other than in that file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With