Does the C++ standard require `#include <math.h>` to define the `abs` overloads found in `<cmath>`?
<p>The C++ standard defines some overloaded functions in the <code>&lt;cmath&gt;</code> header that are not part of the <code>&lt;math.h&gt;</code> header in C (because C doesn't have overloading).
Among these are <code>float abs(float)</code>, <code>double abs(double)</code>, <code>long double abs(long double)</code>, and <code>double abs(Integral)</code>.
On the other hand, <code>abs</code> is not defined in the C <code>&lt;math.h&gt;</code> at all (it is in <code>&lt;stdlib.h&gt;</code> instead) and the only signature is <code>int abs(int)</code>.</p>

<p>Now on my systems, when using a C++ compiler with a C++ program, <code>#include &lt;math.h&gt;</code> does not provide the C++ <code>abs</code> overloads, either in the global namespace or in <code>std</code>.
On the other hand, <code>#include &lt;cmath&gt;</code> defines <code>std::abs</code>.</p>

<p>This is what I'd expect—include the C version to get the C functions, and include the C++ version to get the C++ functions. <a href="https://stackoverflow.com/a/7596625/2132213">This answer</a> by @visitor mentions the same thing.</p>

<p>However, user @Cheers-and-hth-Alf insists that this is a violation of the standard, because it says "Every C header, each of which has a name of the form <code>name.h</code>, behaves as if each name placed in the standard library namespace by the corresponding <em>cname</em> header is placed within the global namespace scope." (This section, D.5.2, doesn't seem to have changed significantly between C++03, C++11, and C++14.)</p>

<p>It's easy enough to check what your platform does: see what happens with</p>

<pre><code>#include &lt;math.h&gt;

int main() {
    abs(1.2);
    return 0;
}
</code></pre>

<p>If <code>abs</code> is not declared, then <code>&lt;math.h&gt;</code> does not include C++ functions.</p>

<p>If it compiles, then try including <code>&lt;stdio.h&gt;</code>
and add <code>printf("%g\n", abs(1.2));</code>
If this complains about a mismatched format, or prints 1, then <code>&lt;math.h&gt;</code>
includes the C <code>int abs(int)</code> function (normally in <code>&lt;stdlib.h&gt;</code>).
(It's best to avoid <code>&lt;iostream&gt;</code> and other C++ headers since they tend to pull in <code>&lt;cstdlib&gt;</code> and confuse the issue.)</p>

<p>Here's what I've found:</p>

<h3>GNU libstdc++</h3>

<pre><code>$ g++ -Wall -Wextra abs2.cc -o abs2
abs2.cc: In function 'int main()':
abs2.cc:5:22: error: 'abs' was not declared in this scope
  std::cout &lt;&lt; abs(1.2) &lt;&lt; '\n';
</code></pre>

<p>The <a href="https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_headers.html#manual.intro.using.headers.cheaders" rel="nofollow noreferrer">libstdc++ docs on the subject</a>
recommend including C++-style headers <code>&lt;c*&gt;</code> rather than C-style headers <code>&lt;*.h&gt;</code> precisely because
C++-style headers use function overloading, and the C-style headers do not.</p>

<h3>Apple libc++</h3>

<pre><code>$ clang++ -Wall -Wextra abs2.cc -o abs2
abs2.cc:4:5: error: use of undeclared identifier 'abs'; did you mean 'fabs'?
</code></pre>

<p>Additionally, if you also include <code>&lt;stdlib.h&gt;</code> to get a definition of <code>abs</code>, clang++ gives
the more helpful error message</p>

<pre><code>abs2.cc:5:5: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value]
    abs(1.2);
    ^
abs2.cc:5:5: note: use function 'std::abs' instead
    abs(1.2);
    ^~~
    std::abs
abs2.cc:5:5: note: include the header &lt;cmath&gt; or explicitly provide a declaration for 'std::abs'
abs2.cc:5:9: warning: implicit conversion from 'double' to 'int' changes value from 1.2 to 1 [-Wliteral-conversion]
    abs(1.2);
    ~~~ ^~~
abs2.cc:5:5: warning: ignoring return value of function declared with const attribute [-Wunused-value]
    abs(1.2);
    ^~~ ~~~
</code></pre>

<p>This explicitly says that the float overloads are only available from <code>&lt;cmath&gt;</code>, not from the
C traditional headers.</p>

<h3>Apache libstdcxx</h3>

<p>I didn't install it, but examining the <a href="http://svn.apache.org/viewvc/stdcxx/trunk/include/ansi/math.h?view=markup" rel="nofollow noreferrer">math.h header</a>, it brings those functions from <code>&lt;cmath&gt;</code> which are also defined in C's <code>&lt;math.h&gt;</code> into the global namespace, but does not include <code>abs</code>.</p>

<h3>OpenWatcom C++</h3>

<p>Again, examining the <a href="https://github.com/open-watcom/open-watcom-v2/blob/c8032600d2aa7fffd916452ae528b31e51d840fa/bld/hdr/watcom/math.mh" rel="nofollow noreferrer">cmath/math.h header</a>,
when used as <code>math.h</code> it brings the same functions into the global namespace as Apache libstdcxx did, not including <code>abs</code>.</p>

<h3>STLPort</h3>

<p>Examining the <a href="https://sourceforge.net/p/stlport/code/ci/master/tree/stlport/math.h" rel="nofollow noreferrer">math.h header</a>, it includes the system's C <code>&lt;math.h&gt;</code> header, which is not part of the C++ library and so doesn't include <code>abs</code>. (This is also what g++ and clang++ did.)</p>

<h3>Microsoft Visual Studio (Dinkumware)</h3>

<p>I don't have access to this myself,
but <a href="http://rextester.com/VPDG81796" rel="nofollow noreferrer">this site</a> claims to compile using Visual C++,
and it says</p>

<pre><code>error C4578: 'abs': conversion from 'double' to 'int', possible loss of data
(Did you mean to call 'fabs' or to #include &lt;cmath&gt;?) 
</code></pre>

<p>So, is literally <em>every</em> major C++ standard library implementation
in violation of the standard on this point?</p>

<p>Or are we missing something that the standard says about <code>&lt;math.h&gt;</code> and other traditional C headers?</p>