c++ - for - llvm 3.7 0
Diferentes comportamientos de g++ y clang++ con entrada de flujo y entero sin signo (1)
Me encontré con una diferencia en el comportamiento, entre gcc (4.9.2) y clang (3.5.0), lo que me sorprendió.
Cuando trato de alimentar un unsigned int
desde un std::istringstream
inicializado con un valor negativo ("-15", en el ejemplo) obtengo
- un error (con
fail()
bit levantado) con clang ++ - la inicialización con
signed(-15)
con gcc ++
Preparé el siguiente programa trivial de ejemplo.
#include <sstream>
#include <iostream>
int main ()
{
std::istringstream iss("-15");
unsigned int ui;
iss >> ui;
std::cout << "ui[" << ui << "] signed(ui)[" << signed(ui)
<< "] flags[" << iss.fail() << iss.good() << iss.bad()
<< iss.eof() << "]/n";
return 0;
}
Con clang ++, obtengo la siguiente salida
ui[0] signed(ui)[0] flags[1001]
Con g ++, obtengo la siguiente salida
ui[4294967281] signed(ui)[-15] flags[0001]
Tengo dos preguntas.
Lo primero es obvio: ¿quién tiene razón? ¿Clang ++, g ++ o es un comportamiento indefinido?
La segunda es: ¿cómo puedo forzar que gcc ++ se comporte como clang ++, dando un error al extraer un valor sin signo de una cadena que comienza con un signo menos?
Gracias y lo siento por mi mal inglés.
EDITAR 2016.04.03
Me di cuenta de que esto no es una diferencia entre g ++ y clang ++, sino una diferencia entre libstd ++ y libc ++.
Compilando y enlazando con clang ++ y libstd ++, obtengo el mismo resultado que obtengo con g ++.
Lo siento.
Esto se ha discutido anteriormente aquí: cadena numérica negativa (por ejemplo, "-10") a corto sin firmar
La respuesta es que de acuerdo con el estándar de C ++ 22.4.2.1.2p3, la conversión debe fallar y los almacenes de valores deben ser:
el valor representable más negativo o cero para un tipo entero sin signo , si el campo representa un valor negativo demasiado grande para ser representado en val. ios_base :: failbit se asigna a err.
Por lo tanto, clang ++ es el comportamiento correcto.