Pregunta

El siguiente código no da una advertencia con G ++ 4.1.1 y -Wall.

int octalStrToInt(const std::string& s)
{    
    return strtol(s.c_str(), 0, 8);
}

Esperaba una advertencia porque Strtol devuelve un long int Pero mi función solo está devolviendo una llanura int. ¿Podrían otros compiladores emitir una advertencia aquí? ¿Debo lanzar el valor de retorno a INT en este caso como una buena práctica?

¿Fue útil?

Solución

Es posible que necesite la bandera -wconversion para activar estas advertencias. Sin embargo, no advertirá sobre largo -> En t, dado que son del mismo tamaño con GCC (el valor no cambiará debido a la conversión). Pero lo haría si se convierte por ejemplo largo -> corto

Supongo que simplemente no se recomendaría hacer un elenco, ya que eso solo cubriría la posibilidad de errores. Estaría bien después de haber verificado que tal elenco no modificará el valor para apaciguar el compilador.

Otros consejos

El mejor enfoque es:

long x = strtol(...); assert(x <= INT_MAX); return (int)x;

Necesitas limits.h y assert.h

Si no tiene acceso a boost::numeric_cast, puedes escribir una imitación simple:

template <typename T, typename S>
T range_check(const S &s) {
    assert(s <= std::numeric_limits<T>::max());
    assert(s >= std::numeric_limits<T>::min());
    return static_cast<T>(s); // explicit conversion, no warnings.
}

return range_check<int>(strtol(some_value,0,8));

En realidad, eso es un poco tramposo, ya que no funciona para los tipos de destino de puntos flotantes. min() ¿No es el mismo encuadernado para ellos que para los tipos enteros, debe consultar con +/- max(). Ejercicio para el lector.

Ya sea que use Afirmar o algún otro manejo de errores depende de lo que realmente desee hacer con la entrada no válida.

También hay boost::lexical_cast (fuera de la mano, no sé cómo hacer esa lectura octal) y stringstream. Lea el tipo que desea, no el tipo que tiene una función de biblioteca C para ello.

No ve ninguna advertencia aquí, porque los tipos de datos "int" e "long int" en su plataforma tienen el mismo tamaño y rango. Dependiendo de la arquitectura, podrían volverse diferentes.

Para protegerse de errores extraños, use la verificación de rango. Le sugiero que use std :: numeric_limits :: min/max (ver).

Después de la verificación de rango, puede usar de forma segura static_cast o el elenco de estilo C.

Por otro lado, puede confiar en la misma funcionalidad implementada en la clase STD :: Stringstream. La conversión con std :: stringstream será segura a la plataforma y tipo segura de forma predeterminada.

La mayoría de los compiladores modernos advertirán sobre la conversión y el posible truncamiento dependiendo del nivel de advertencia que haya configurado. En MSVC, ese es el nivel de advertencia 4.

La mejor práctica sería devolver un largo de su función y dejar que el código de llamadas decida cómo manejar la conversión. Salvo eso, al menos asegúrese de que el valor que obtenga de STRTOL se ajuste a un INT antes de regresar, como lo sugiere LET_ME_BE.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top