私が話しているのは::abs()
ではなく、注意してくださいstd::abs()
cplusplus.com の Web サイトによると、 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
(double から int へのキャストは通知されません)。に置き換えg++
ても結果は同じですllvm-g++
。math.h
orを含めることはcmath
、コンパイルには必要ありません。 - プログラムの出力は次のとおりです。
x=-1.5 ax=1
最後に Linux での結果:
- が含まれていない場合、プログラムはコンパイルされません (最後に、自動的
stdlib.h
に含まれない 1 つのコンパイラ)。stdlib
double -> int キャストに対してコンパイル警告は発行されません。 - プログラムの出力は次のとおりです。
x=-1.5 ax=1
ここには明確な勝者はありません。std::abs
明白な答えが「好む」であることは知っていますが::abs
、私は疑問に思います:
- cplusplus.com の Web サイトは、名前空間
abs
の外側で自動的に二重バージョンを提供する必要があると言っていますが、ここにありますか?std
- ここでは、MSVC を除いてすべてのコンパイラとその標準ライブラリが間違っています
math.h
か (サイレントに含まれています)。