当心,我说的是::abs()
,不是std::abs()
根据cplusplus.com 网站, h C 版本abs
的行为应该不同stdlib.
,如果你包括<cmath>
这是此页面的摘录(涉及::abs
,而不是std::abs
):
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 <cstdlib> (and operates on int values).
The additional overloads are provided in this header (<cmath>) for the integral types:
These overloads effectively cast x to a double before calculations
(defined for T being any integral type).
*/
真的???
在将程序移植到新平台时,我一直对此感到困扰,因为不同的编译器和标准库的实现在这里有所不同。
这是我的示例程序:
#include <iostream>
//#include <stdlib.h>//Necessary inclusion compil under linux
//You can include either cmath or math.h, the result is the same
//#include <cmath>
#include <math.h>
int main(int argc, const char * argv[])
{
double x = -1.5;
double ax = std::abs(x);
std::cout << "x=" << x << " ax=" << ax << std::endl;
return 0;
}
这是 MSVC 2010 下的结果:
- 在 MSVC 2010 下不会发出编译警告,即使您既不包含 math.h 也不包含该程序也会编译:无论您做什么,
stdlib.h
它似乎总是包含在内math.h
stdlib.h
- 程序输出是:(
x=-1.5 ax=1.5
根据参考似乎正确)
现在这是 OSX 下的结果:
- 即使有标志,也不会发出编译警告
-Wall
(没有发出双重到 int 的信号)!如果替换为 ,结果是一样g++
的llvm-g++
。编译时不需要包含math.h
或。cmath
- 程序输出为:
x=-1.5 ax=1
最后是Linux下的结果:
- 如果不包含,程序将无法编译
stdlib.h
(最后,一个不stdlib
自动包含的编译器)。对于 double -> int 强制转换,不会发出编译警告。 - 程序输出为:
x=-1.5 ax=1
这里没有明显的赢家。我知道一个明显的答案是“喜欢std::abs
” ::abs
,但我想知道:
- 当 cplusplus.com 网站说
abs
应该在命名空间之外自动提供双重版本时,它是否就在这里std
? math.h
除了 MSVC(尽管它默默地包含),这里所有的编译器及其标准库都错了吗?