abs vs std :: abs, o que a referência diz?
Cuidado, eu estou falando sobre::abs()
, nãostd::abs()
De acordo comsite cplusplus.com, abs
deve se comportar de maneira diferente para ostdlib.
h versão C, se você incluir<cmath>
Aqui está um extrato desta página (que lida com::abs
, nãostd::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).
*/
Realmente???
Fui mordido por isso ao transportar um programa para uma nova plataforma, pois diferentes compiladores e implementação de bibliotecas padrão diferem aqui.
Aqui está o meu exemplo de programa:
#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;
}
E aqui está o resultado no MSVC 2010:
Nenhum aviso de compilação é emitido no MSVC 2010 e o programa será compilado mesmo que você não inclua math.h nemstdlib.h
: parece quemath.h
estdlib.h
sempre são incluídos o que você fazA saída do programa é:x=-1.5 ax=1.5
(aparentemente correto de acordo com a referência)Agora, aqui está o resultado no OSX:
Nenhum aviso de compilação é emitido, mesmo com o-Wall
flag (a conversão dupla para int não é sinalizada)! O resultado é o mesmo se você substituirg++
porllvm-g++
. A inclusão demath.h
oucmath
não é necessário para a compilação.A saída do programa é:x=-1.5 ax=1
E, finalmente, o resultado no Linux:
O programa não será compilado sestdlib.h
não está incluído (finalmente, um compilador que não incluistdlib
automaticamente). Nenhum aviso de compilação é emitido para o double -> int cast.A saída do programa é:x=-1.5 ax=1
Nenhum vencedor claro aqui. Eu sei que uma resposta óbvia é "prefirostd::abs
para::abs
", mas eu me pergunto:
abs
deve fornecer automaticamente a versão dupla fora dostd
namespace?Todos os compiladores e suas bibliotecas padrão estão errados aqui, exceto o MSVC (embora incluamath.h
silenciosamente)?