abs vs std :: abs,参考文献怎么说? [英] abs vs std::abs, what does the reference say?

查看:169
本文介绍了abs vs std :: abs,参考文献怎么说?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当心,我说的是 :: 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 like math.h and stdlib.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 replace g++ by llvm-g++. The inclusion of math.h or cmath 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 include stdlib 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 the std 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 in std::. Practically, only export was less respected, and different compilers did very different things. If you included <cmath>, you used std:: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆