abs vs std :: abs,参考文献怎么说? [英] abs vs std::abs, what does the reference say?
问题描述
当心,我说的是 :: abs()
,而不是 std :: abs()
Beware, I am talking about ::abs()
, not std::abs()
根据 cplusplus.com网站,<$对于 stdlib,c $ c> abs
的行为应有所不同。 h C版本,如果包含< cmath> ;
According to the cplusplus.com website, abs
is supposed to behave differently for the stdlib.
h C version, if you include <cmath>
这里是此页的摘录(处理 :: abs
,而不是 std :: abs
):
Here is an extract from the this page (which deals with ::abs
, not 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).
*/
真的吗?
在将程序移植到新平台时,由于不同的编译器和标准库的实现在这里有所不同,我对此颇为bit恼。
I have been bitten by this when porting a program to a new platform, since different compilers and standard libraries implementation differ here.
这是我的示例程序:
#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下的结果:
And here is the result under MSVC 2010:
- 在MSVC 2010下不会发出编译警告,即使您不包括math.h也不包含
stdlib.h <,程序也将编译。 / code>:无论您做什么,似乎总是包含
math.h
和stdlib.h
- 程序输出为:
x = -1.5 ax = 1.5
(根据参考资料看似正确)
- No compilation warning is emitted under MSVC 2010, and the program will compile even if you do not include neither math.h nor
stdlib.h
: it seems likemath.h
andstdlib.h
are always included whatever you do - The program output is:
x=-1.5 ax=1.5
(seemingly correct according to the reference)
现在这是OSX下的结果:
Now here is the result under OSX:
- 没有编译警告即使使用
-Wall
标志也不会发出(不指示对double进行强制转换)!如果将g ++
替换为llvm-g ++
,则结果相同。编译不需要包含math.h
或cmath
。 - 程序输出为:
x = -1.5 ax = 1
- No compilation warning is emitted, even with the
-Wall
flag (the double to int cast is not signaled)! The result is the same if you replaceg++
byllvm-g++
. The inclusion ofmath.h
orcmath
is not required for the compilation. - The program output is:
x=-1.5 ax=1
最后是Linux下的结果:
And finally the result under Linux:
- 如果
stdlib.h
不包括在内(最后,一个不自动包含stdlib
的编译器)。 - 程序输出为:
x = -1.5 ax = 1
- The program will not compile if
stdlib.h
is not included (at last, one compiler that does not includestdlib
automatically). No compilation warning is emitted for the double -> int cast. - The program output is:
x=-1.5 ax=1
这里没有明显的赢家。我知道一个明显的答案是首选 std :: abs
比 :: abs
,但是我想知道:
No clear winner here. I know that an obvious answer is "prefer std::abs
to ::abs
", but I wonder:
- 当cplusplus.com网站显示
abs
应该自动提供时,该网站是否位于此处std
命名空间之外的双版本? - 除了MSVC之外,所有编译器及其标准库在这里都出错了吗(尽管它包括
math.h
静默)?
- Is the cplusplus.com website right here when it says that
abs
should automatically provide double version outside of thestd
namespace? - Are all compiler and their standard libraries wrong here except MSVC (although it includes
math.h
silently)?
推荐答案
官方参考资料说...很乱。 C ++ 11和C11之前的版本:
The official references say... it's a mess. Pre-C++11 and C11:
-
正式包括
< cmath>
在::
中什么也没有引入;
所有功能都在std ::
中。实际上,只有
export
受到较少的尊重,并且不同的编译器所做的
所做的事情非常不同。如果您包含< cmath>
,则在各处使用std ::
,或者您得到的变化从编译器到编译器。
Officially, including
<cmath>
introduced nothing in::
; all of the functions were instd::
. Practically, onlyexport
was less respected, and different compilers did very different things. If you included<cmath>
, you usedstd::
everywhere, or what you got varied from compiler to compiler.
C没有提供任何重载: abs
占用了 int
,并且是
在< stdlib.h>
, fabs
拿了双
,并且是在< math.h>
中声明的
。
C didn't provide any overloads: abs
took an int
, and was
declared in <stdlib.h>
, fabs
took double
, and was
declared in <math.h>
.
如果在C ++中包含< math.h>
,则不清楚
是什么得到了,但是由于实施者似乎都不在乎标准中的
(请参见上面的第一点)...
If you included <math.h>
in C++, it's not clear what you
got, but since none of the implementers seemed to care about
the standard anyway (see the first point above)...
粗略地说,您包括了< cmath>
,并在所有
的前缀前加上了 std ::
,或者您包含了< math.h>
,而
使用了 fabs
如果您想支持浮点(以及
除 int
或 double
以外的类型的各种后缀) )。
Roughly speaking, either you included <cmath>
, and prefixed
all of the uses with std::
, or you included <math.h>
, and
used fabs
if you wanted support for floating point (and the
various suffixes for types other than int
or double
).
C ++ 11和C11增加了一些新的变化:
C++11 and C11 added a few new twists:
-
< cmath>
:: 中引入
符号。还有另一件事,根据实现的不同,
可能会有所不同。 (此处的目标是使
现有实现保持一致。)
<cmath>
is now allowed (but not required) to introduce the symbols in::
as well. One more thing which can vary depending on the implementation. (The goal here was to make existing implementations conformant.)
C具有新的标头< tgmath。 h>
,它使用编译器魔术来使
使< math.h>
中的函数的行为就像它们是
如C ++中那样重载。 (因此,它不适用于 abs
,但是只有
到 fabs
。)此标头具有 not 已添加到C ++中,这是因为
的明显原因是C ++不需要
的任何编译器魔术。
C has a new header, <tgmath.h>
, which uses compiler magic to
make the functions in <math.h>
behave as if they were
overloaded as in C++. (So it doesn't apply to abs
, but only
to fabs
.) This header had not been added to C++, for the
obvious reason that C++ doesn't need any compiler magic for
this.
总而言之,情况略有恶化,我上面的
建议仍然成立。包括< math.h>
和
< stdlib.h>
并使用 abs
/ fabs
及其派生产品(例如
labs
, fabsf
等),或包含< cmath>
,而
使用 std :: abs
。还有其他事情,您会遇到
可移植性问题。
All in all, the situation has become slightly worse, and my
recommendations above still hold. Include either <math.h>
and
<stdlib.h>
, and use abs
/fabs
and their derivated (e.g.
labs
, fabsf
, etc.) exclusively, or include <cmath>
, and
use std::abs
exclusively. Anything else, and you'll run into
portabiity problems.
这篇关于abs vs std :: abs,参考文献怎么说?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!