They are ordinarily the same function. The name of the library is libm
(“m” for “math”), like many other Unix systems, and you get the same function whether you access that function through the <math.h>
header or the <cmath>
header.
The actual way these headers work is kind of complicated. I will say that in this case, you are probably just getting the ordinary cos
function, no matter whether you call it through <math.h>
as cos(x)
or calling it through <cmath>
as std::cos(x)
.
Assembly
Here’s a test function. You can paste this into Godbolt (https://gcc.godbolt.org/) and follow along.
#include <cmath>
double my_function(double x)
{
return std::cos(x);
}
At -O2
, this becomes:
my_function(double):
jmp cos
Here’s another test function:
#include <math.h>
double my_function(double x)
{
return ::cos(x);
}
Here’s the result at -O2
:
my_function(double):
jmp cos
It is exactly the same. You get exactly the same function either way. It is just a different interface.
More Tests
#include <math.h>
#include <cmath>
#include <cstdio>
int main(int argc, char **argv) {
int maxv = 1000000;
for(int i = 0; i < maxv; i++) {
double x = static_cast<double>(i) / static_cast<double>(maxv);
std::printf("diff = %f\n", cos(x) - std::cos(x));
}
}
This prints diff = 0.000000
over and over again.
If you look at how the GCC optimizes this function, you’ll even see that it doesn’t actually call cos
twice—it calls cos
once, because it knows that the result will be the same both times. (It is unable to completely optimize out the call to cos
, maybe because it does not successfully determine that the output to cos
is finite in every loop iteration.)