c++ - ejemplos - abs vs std:: abs, ¿qué dice la referencia?
sqrt c++ (1)
Las referencias oficiales dicen ... es un desastre. Pre-C ++ 11 y C11:
Oficialmente, incluyendo
<cmath>
no introdujo nada en::
; todas las funciones estaban enstd::
. En la práctica, solo laexport
era menos respetada y los compiladores diferentes hacían cosas muy diferentes. Si incluyó<cmath>
, usóstd::
everywhere, o lo que obtuvo varió de compilador a compilador.C no proporcionó ninguna sobrecarga:
abs
tomó unint
, y se declaró en<stdlib.h>
,fabs
tomó eldouble
y se declaró en<math.h>
.Si incluyó
<math.h>
en C ++, no está claro lo que obtuvo, pero dado que a ninguno de los implementadores parecía importarle el estándar de todos modos (vea el primer punto arriba) ...
En términos generales, incluyó <cmath>
y prefijó todos los usos con std::
, o incluyó <math.h>
, y usó fabs
si quería soporte para punto flotante (y los diversos sufijos para tipos distintos de int
o double
).
C ++ 11 y C11 añadieron algunos nuevos cambios:
<cmath>
ahora está permitido (pero no es obligatorio) para introducir los símbolos en::
también. Una cosa más que puede variar dependiendo de la implementación. (El objetivo aquí era hacer que las implementaciones existentes sean conformes).C tiene un nuevo encabezado,
<tgmath.h>
, que utiliza la magia del compilador para hacer que las funciones en<math.h>
comporten como si estuvieran sobrecargadas como en C ++. (Por lo tanto, no se aplica a losabs
, sino solo afabs
.) Este encabezado no se agregó a C ++, por la razón obvia de que C ++ no necesita ninguna magia de compilación para esto.
Con todo, la situación ha empeorado un poco, y mis recomendaciones anteriores siguen siendo válidas. Incluya <math.h>
y <stdlib.h>
, y use abs
/ fabs
y sus derivados (por ejemplo, labs
, fabsf
, etc.) exclusivamente, o incluya <cmath>
, y use std::abs
exclusivamente. Cualquier otra cosa, y se encontrará con problemas de portabiity.
Cuidado, estoy hablando de ::abs()
, no std::abs()
De acuerdo con el sitio web cplusplus.com , se supone que los abs
se comportan de manera diferente para el stdlib.
h versión C, si incluye <cmath>
Aquí hay un extracto de esta página (que trata de ::abs
, no 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).
*/
¿¿¿De Verdad???
Esto me ha mordido al trasladar un programa a una nueva plataforma, ya que los compiladores diferentes y la implementación de bibliotecas estándar difieren aquí.
Aquí está mi programa de muestra:
#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;
}
Y aquí está el resultado bajo MSVC 2010:
- No se emiten advertencias de compilación bajo MSVC 2010, y el programa se compilará incluso si no incluye math.h ni
stdlib.h
: parece quemath.h
stdlib.h
siempre se incluyen en lo que sea que haga - La salida del programa es:
x=-1.5 ax=1.5
(aparentemente correcta de acuerdo con la referencia)
Ahora aquí está el resultado bajo OSX:
- No se emiten avisos de compilación, incluso con la
-Wall
(el doble al int cast no está señalado). El resultado es el mismo si reemplazag++
porllvm-g++
. La inclusión demath.h
ocmath
no es necesaria para la compilación. - La salida del programa es:
x=-1.5 ax=1
Y finalmente el resultado bajo Linux:
- El programa no se compilará si no se incluye
stdlib.h
(por último, un compilador que no incluye automáticamentestdlib
). No se emite ninguna advertencia de compilación para el doble -> int cast. - La salida del programa es:
x=-1.5 ax=1
No hay ganador claro aquí. Sé que una respuesta obvia es "prefiero std::abs
a ::abs
", pero me pregunto:
- ¿Está el sitio web cplusplus.com aquí cuando dice que los
abs
deberían proporcionar automáticamente una versión doble fuera delstd
nombresstd
? - ¿Todos los compiladores y sus bibliotecas estándar están equivocados aquí excepto MSVC (aunque incluye
math.h
silencio)?