2012-01-30 10 views
13

Al utilizar la variante double de la función std::abs() sin el std con g ++ 4.6.1, no se muestra ninguna advertencia o error.Evitar problemas del compilador con abs()

#include <algorithm> 
#include <cmath> 

double foobar(double a) 
{ 
    return abs(a); 
} 

Esta versión de g ++ parece estar tirando en la variante de double de abs() en el espacio de nombres global a través de uno de los incluye de algorithm. Esto parece que ahora está permitido por el estándar (vea esto question), pero no es obligatorio.

Si puedo compilar el código anterior utilizando un compilador que no tira la variante double de abs() en el espacio de nombres global (como g ++ 4.2), entonces el siguiente error se informa:

warning: passing 'double' for argument 1 to 'int abs(int)' 

¿Cómo puedo forzar g ++ 4.6.1, y otros compiladores que extraen funciones en el espacio de nombres global, para dar una advertencia para que pueda evitar errores cuando se usa con otros compiladores?

+3

¿Qué tiene de malo usar 'std :: abs' si esa es la función que necesita? –

+3

@JonathanLeffler Nada, pero puede ser fácil perderse por error. No quiero que ese deslizamiento pase desapercibido y cause problemas de compilación con otros compiladores. –

Respuesta

8

La función que está utilizando en realidad es la versión entera de abs, y GCC realiza una conversión implícita a entero.

esto puede ser verificado por un programa de prueba sencilla:

#include <iostream> 
#include <cmath> 

int main() 
{ 
    double a = -5.4321; 
    double b = std::abs(a); 
    double c = abs(a); 

    std::cout << "a = " << a << ", b = " << b << ", c = " << c << '\n'; 
} 

de salida es:

 
a = -5.4321, b = 5.4321, c = 5 

Para una advertencia sobre esto, colocar la bandera a -Wconversion g ++. En realidad, la documentación de GCC para esa opción menciona explícitamente llamar a abs cuando el argumento es double. Todas las opciones de advertencia se pueden encontrar en here.

+0

El código de muestra no coincide con la salida. –

+0

@SamDeHaan Lo sentimos, actualizé el resultado pero olvidé actualizar el código. :) –

+0

¿Es el estándar que ha cambiado o un cambio en la implementación de g ++ lo que causa la conversión implícita con 4.6.1 y no 4.2? ¿Son ambos validos? –

Cuestiones relacionadas