title: abs vs std::abs, what does the reference say?
body: <p>Beware, I am talking about <code>::abs()</code>, not <code>std::abs()</code></p>
  
  <p>According to the <a href="http://www.cplusplus.com/reference/cmath/abs/">cplusplus.com website</a>, <code>abs</code> is supposed to behave differently for the <code>stdlib.</code>h C version, if you include <code>&lt;cmath&gt;</code></p>
  
  <p>Here is an extract from the this page (which deals with <code>::abs</code>, not <code>std::abs</code>):</p>
  
  <pre><code>double abs (double x); 
  float abs (float x); 
  long double abs (long double x);
  Compute absolute value
  /*
  Returns the absolute value of x: |x|.
  These convenience abs overloads are exclusive of C++. In C, abs is only declared
  in  &lt;cstdlib&gt; (and operates on int values). 
  The additional overloads are provided in this header (&lt;cmath&gt;) for the integral types: 
  These overloads effectively cast x to a double before calculations 
  (defined for T being any integral type).
  */
  </code></pre>
  
  <p><em>Really???</em></p>
  
  <p>I have been bitten by this when porting a program to a new platform, since different compilers and standard libraries implementation differ here.</p>
  
  <p>Here is my sample program: </p>
  
  <pre><code>#include &lt;iostream&gt;
  //#include &lt;stdlib.h&gt;//Necessary inclusion compil under linux
  //You can include either cmath or math.h, the result is the same
  //#include &lt;cmath&gt;
  #include &lt;math.h&gt;
  int main(int argc, const char * argv[])
  {
    double x = -1.5;
    double ax = std::abs(x);
    std::cout &lt;&lt; "x=" &lt;&lt; x &lt;&lt; " ax=" &lt;&lt; ax &lt;&lt; std::endl;
    return 0;
  }
  </code></pre>
  
  <p>And here is the result under MSVC 2010:</p>
  
  <ul>
  <li>No compilation warning is emitted under MSVC 2010, and the program will compile even if you do not include neither math.h nor <code>stdlib.h</code>: it seems like <code>math.h</code> and <code>stdlib.h</code> are always included whatever you do</li>
  <li>The program output is: <code>x=-1.5 ax=1.5</code> (seemingly correct according to the reference)</li>
  </ul>
  
  <p>Now here is the result under OSX:</p>
  
  <ul>
  <li>No compilation warning is emitted, even with the <code>-Wall</code> flag (the double to int cast is not signaled)! The result is the same if you replace <code>g++</code> by <code>llvm-g++</code>. The inclusion of <code>math.h</code> or <code>cmath</code> is not required for the compilation.</li>
  <li>The program output is: <code>x=-1.5 ax=1</code></li>
  </ul>
  
  <p>And finally the result under Linux:</p>
  
  <ul>
  <li>The program will not compile if <code>stdlib.h</code> is not included (at last, one compiler that does not include <code>stdlib</code> automatically). No compilation warning is emitted for the double -> int cast.</li>
  <li>The program output is: <code>x=-1.5 ax=1</code></li>
  </ul>
  
  <p>No clear winner here. I know that an obvious answer is "prefer <code>std::abs</code> to <code>::abs</code>", but I wonder:</p>
  
  <ul>
  <li>Is the cplusplus.com website right here when it says that <code>abs</code> should automatically provide double version outside of the <code>std</code> namespace?</li>
  <li>Are all compiler and their standard libraries wrong here except MSVC (although it includes <code>math.h</code> silently)?</li>
  </ul>