c++ c++11 compiler-errors type-conversion language-lawyer

c++ - conversión de nullptr_t a bool: ¿válido o no?



c++11 compiler-errors (1)

Probé el siguiente código con 3 compiladores y obtuve 3 resultados diferentes: error, advertencia y autorización.

  • GCC (5.3): error: conversión inválida definida por el usuario de ''std :: nullptr_t'' a ''const Thing &''
  • Clang (3.8): advertencia: conversión implícita de la constante nullptr a ''bool''
  • MSVC (14.1): sin error, sin advertencia

¿Qué compilador es correcto? Sé que es una conversión trivial entre un tipo de puntero y bool . Pero ¿qué pasa con std::nullptr_t y bool ?

(Al final, Clang y MSVC están de acuerdo con el código. Clang es un poco más detallado de una manera positiva.)

struct Thing { Thing(bool) {} }; void addThing(const Thing&){} int main() { addThing(nullptr); // warning or error on this line }


Esto no es válido De acuerdo con la regla de conversiones booleanas :

Un prvalue de tipo std::nullptr_t , incluido nullptr , se puede convertir a un prvalue de tipo bool en el contexto de la inicialización directa. El valor resultante es false .

Citas de la norma, §7.14 / 1 conversiones booleanas [conv.bool]

Para la inicialización directa, un prvalue de tipo std​::​nullptr_t se puede convertir a un prvalue de tipo bool ; el valor resultante es false .

La conversión solo se permite para la inicialización directa , pero no para la inicialización de la copia , lo que incluye el caso para pasar el argumento a una función por valor. p.ej

bool b1 = nullptr; // invalid bool b2 {nullptr}; // valid

Entonces GCC es correcto. Pero Clang tampoco está equivocado; el estándar solo requiere que el compilador "emita un diagnóstico" cuando el programa está mal formado, por lo que debe decirle que algo sucede, después de eso podría hacer cualquier cosa.

Consulte ¿Especifica el estándar de C ++ que, en algunos casos, la compilación debe fallar con un error?