title: How can I avoid unexpected results from std::abs?
body: <p>I've come across a few different examples of ways in which <code>std::abs</code> can give unexpected results:</p>
  
  <ol>
  <li>This question (<a href="https://stackoverflow.com/questions/13460750/on-the-stdabs-function">On the std::abs function</a>) points out that <code>&lt;cstdlib&gt;</code> provides overloads for integral types while <code>&lt;cmath&gt;</code> provides overloads for floating point types. Failing to include the correct header gives undefined behaviour, which the compiler is allowed to silently accept</li>
  <li>C++ <a href="https://cplusplus.github.io/LWG/issue2735" rel="noreferrer">Defect report 2735</a> points out that the C++11 and C++14 standards technically require that <code>std::abs(short)</code> returns a <code>double</code>, although most compilers ignore the relevant wording and return an <code>int</code>. The resolution to this issue indicates that the wording was changed in C++17 so that <code>std::abs(short)</code> returns an <code>int</code></li>
  <li>The answers to this question (<a href="https://stackoverflow.com/questions/3118165/when-do-i-use-fabs-and-when-is-it-sufficient-to-use-stdabs">When do I use fabs and when is it sufficient to use std::abs?</a>)  point out that relying on <code>std::abs</code> can lead to difficult-to-spot bugs, since (in modern C++) the headers which introduce <code>std::abs</code> are allowed to introduce a global <code>abs</code> function (which may or may not have the same overloads), and it's easy to accidentally use <code>abs</code> instead of <code>std::abs</code></li>
  </ol>
  
  <p>The fixes that I am aware of are:</p>
  
  <ol>
  <li>Avoid undefined behaviour: include <code>&lt;cstdlib&gt;</code> if evaluating <code>std::abs([integral type])</code> and <code>&lt;cmath&gt;</code> if evaluating <code>std::abs([floating point type])</code></li>
  <li>Two options:
  
  <ul>
  <li>Use C++17 or pre-(C++11)</li>
  <li>Work around the fact that <code>std::abs(short)</code> may return an <code>int</code> or a <code>double</code> depending on the compiler's compliance with the C++11/C++14 standard</li>
  </ul></li>
  <li>Two options:
  
  <ul>
  <li>Pass gcc the flag <code>–Wconversion</code> so that calls like <code>abs(2.0)</code> trigger a warning at compilation</li>
  <li>Use a trick (adapted from n.m.'s answer to (<a href="https://stackoverflow.com/questions/19159541/disable-math-h-crap-when-working-with-cmath">Disable math.h crap when working with cmath</a>)) to make to the global <code>abs</code> ambiguous</li>
  </ul></li>
  </ol>
  
  <p>Trick:</p>
  
  <pre><code>namespace neveruse{
      int abs(int);
  }
  
  using namespace neveruse;
  </code></pre>
  
  <p><strong>Question:</strong> 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?</p>