c++ type-conversion language-lawyer iso

¿El estándar de C++ especifica que, en algunos casos, la compilación debería fallar con un error?



type-conversion language-lawyer (5)

El único requisito para un programa mal formado es que el compilador debe "emitir un diagnóstico", donde "diagnóstico" tiene un significado definido por la implementación. Una vez hecho esto, el compilador es libre de continuar compilando el código. Ese es el gancho principal para el comportamiento específico de la implementación.

Estoy comprobando el estándar sobre la reducción de conversión, y creo que para una conversión de reducción se debe activar un error. Porque la standard dice:

[Nota: como se indicó anteriormente, tales conversiones no están permitidas en el nivel superior en las inicializaciones de lista. - nota final]

Creo que la descripción de "no permitido" significa que la compilación debería fallar.

Pero alguien me dijo que here solo dice "el programa está mal formado", y el estándar no requiere que la compilación deba fallar.

Si se requiere una conversión de reducción (ver más abajo) para convertir el elemento a T, el programa no está bien formado.

Entonces mi pregunta es: ¿el estándar especifica si se debe generar un error o advertencia? ¿O para algunos casos la compilación debería fallar? Desde el aspecto de un compilador, ¿está bien hacer que el programa se compile y solo dar algunas advertencias?

BTW: Clang 4.0.0 y Gcc 7.0.0 se comportan de manera diferente.

float a {1.e39}; // Error for both Clang and GCC double d; float a3{d}; // Error for Clang, warning for GCC


El estándar no usa los términos "error" y "advertencia", solo habla de casos donde el compilador debe "emitir un diagnóstico".

En su ejemplo, si el programa está "mal formado", el compilador debe decirle que de alguna manera - emita un diagnóstico.

Después de eso, puede hacer lo que quiera, incluso compilar y ejecutar el programa de todos modos. El estándar solo especifica lo que sucede para el código conforme, todo lo demás está indefinido. Y entonces, como sabemos, cualquier cosa puede pasar.


Las notas en el estándar no son normativas y no afectan la definición del idioma. Por lo tanto, la nota en su primera cita no es importante desde la perspectiva de un abogado lingüístico.

Dicho esto, creo que ambas citas tienen el mismo significado. Un "programa mal formado" es uno que no se construye de acuerdo con las reglas de sintaxis, las reglas semánticas diagnosticables y una regla de definición de la norma (el énfasis es mío). Si una cierta semántica no está "permitida", eso solo significa que viola una regla semántica diagnosticable de las langugae, y por lo tanto solo significa que está mal formada.

El compilador debe emitir un diagnóstico para un programa que está mal formado. Después de eso, el compilador puede hacer lo que quiera. El estándar no especifica ninguna condición bajo la cual la compilación debe fallar.


Si un programa no está mal formado (y no tiene UB), el compilador tiene que producir una salida ejecutable. Si un programa tiene un formato incorrecto, el estándar no plantea ninguna restricción sobre si hay o no una salida.

Si un programa está mal formado y eso no es NDR, se debe producir un diagnóstico . El estándar no diferencia entre advertencias o errores.


Si un programa no está mal formado, el compilador debe producir una salida ejecutable. Si el programa no contiene UB, el ejecutable debe comportarse como la máquina abstracta que describe el estándar y sus estados. Si contiene UB, el ejecutable puede hacer cualquier cosa.

Si el programa está mal formado y no se requiere diagnóstico, el compilador puede hacer cualquier cosa. Puede producir una salida ejecutable, o no. Esa salida ejecutable puede hacer cualquier cosa en absoluto. Podría diseñar un programa que parezca coincidir con la intención del código, por ejemplo.

Los compiladores son libres de imprimir diagnósticos cuando lo deseen.

Los compiladores tienen el mandato de imprimir diagnósticos en algunas situaciones. "La mayoría de los programas mal formados requieren un diagnóstico. Lo que un diagnóstico es exactamente es la implementación definida. Se ha observado que la impresión de una nueva línea nueva en blanco, o un espacio, es un diagnóstico válido según la norma.

Eso sería considerado una mala calidad de implementación.

Una vez que se imprime el diagnóstico cuando hay un programa mal formado que requiere un diagnóstico, el compilador es libre de hacer cualquier cosa. Puede producir un ejecutable que coincida de alguna manera con lo que pides, producir un ejecutable que haga lo que quiera, o no producir ningún ejecutable.

El estándar no distingue entre advertencias y errores.

Un programa mal formado que requiere un diagnóstico que imprime una advertencia, luego continúa compilando, no viola el estándar.

Un programa mal formado que requiere un diagnóstico que imprime un error, luego no continúa compilando, no viola el estándar.

Un programa mal formado que no requiere diagnóstico puede imprimir un diagnóstico. Puede optar por producir un ejecutable o no. El ejecutable podría hacer algo razonable o no.

Un programa bien formado puede hacer que el compilador emita un diagnóstico. Este diagnóstico podría ser descrito como una advertencia. También podría describirse como un error, pero el compilador debe producir un ejecutable, y el ejecutable debe hacer lo que los mandatos estándar.