installed for c++ clang++ libstdc++ libc++ istringstream

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.