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