¿Debería fallar la lectura negativa en unsigned a través de std ::cin (gcc, clang discrepar)?

 C Programming >> Programación C >  >> Tags >> Clang
¿Debería fallar la lectura negativa en unsigned a través de std ::cin (gcc, clang discrepar)?

Creo que ambos están mal en C++17 1 y que el resultado esperado debería ser:

4294967295 0

Si bien el valor devuelto es correcto para las últimas versiones de ambos compiladores, creo que ios_­base​::​failbit debe establecerse, pero también creo que hay una confusión sobre la noción de campo a convertir en el estándar que puede dar cuenta de los comportamientos actuales.

El estándar dice:[facet.num.get.virtuals#3.3]:

Así que recurrimos a std::strtoull , que debe devolver 2 ULLONG_MAX y no establecer errno en este caso (que es lo que hacen ambos compiladores).

Pero en el mismo bloque (énfasis es mía):

Tenga en cuenta que todas estas conversaciones sobre el "campo a convertir" y no el valor real devuelto por std::strtoull . El campo aquí es en realidad la secuencia ampliada del carácter '-', '1' .

Dado que el campo representa un valor (-1) que no se puede representar con un unsigned , el valor devuelto debe ser UINT_MAX y el bit de falla debe establecerse en std::cin .

1 clang en realidad tenía razón antes de C++17 porque la tercera viñeta en la cita anterior era:

2 std::strtoull devuelve ULLONG_MAX porque (gracias @NathanOliver) — C/7.22.1.4.5:


La pregunta es sobre las diferencias entre las implementaciones de la biblioteca libc++ y libstdc++, y no tanto sobre las diferencias entre los compiladores (clang, gcc).

cppreference aclara estas inconsistencias bastante bien:

Esto se resume a:

  • ULLONG_MAX (4294967295 ) es correcto en el futuro, ya que c++17 (ambos compiladores lo hacen correctamente ahora)
  • Anteriormente debería haber sido 0 con una lectura estricta del estándar (libc++)
  • Algunas implementaciones (notablemente libstdc++) siguieron std::strtoull protocolo en su lugar (que ahora se considera el comportamiento correcto)

El conjunto de bits de falla y por qué se configuró, podría ser una pregunta más interesante (al menos desde la perspectiva del abogado de idiomas). En la versión 7 de libc++ (clang) ahora hace lo mismo que libstdc++; esto parece sugerir que se eligió para ser igual que en el futuro (aunque esto va en contra de la letra del estándar, que debería ser cero antes de c++17 ), pero hasta ahora no he podido encontrar el registro de cambios o la documentación para este cambio.

El interesante bloque de texto dice (suponiendo que sea anterior a c++17):

De acuerdo con esto, el valor se especifica para ser 0 . Además, en ninguna parte se indica que esto deba resultar en la configuración del bit de error.