¿El estándar C++ especifica que en algunos casos la compilación debe fallar con un error?


Estoy comprobando el estándar sobre la conversión de estrechamiento, y creo que para una conversión de estrechamiento se debería activar un error. Porque el estándar dice:

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

Creo que la descripción de "no permitido" significa que la compilación debe fallar.

Pero alguien me dijo que aquí solo dice "el programa está mal formado", y el standard no requerirá que la compilación falle.

Si se requiere una conversión de estrechamiento (ver a continuación) para convertir elemento a T, el programa está mal formado.

Así que mi pregunta es: ¿El estándar especifica si se debe generar un error o una advertencia? O para algunos casos la compilación falla? Desde el punto de vista de un compilador, ¿está bien hacer que el programa compile y solo dar algunas advertencias?

BTW: Clang 4.0.0 y Gcc 7.0.0 compórtate diferente.

float a {1.e39}; // Error for both Clang and GCC
double d;
float a3{d};     // Error for Clang, warning for GCC
Author: songyuanyao, 2016-11-25

5 answers

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

En su ejemplo, si el programa está "mal formado", se requiere que el compilador le diga que de alguna manera-emitir un diagnóstico.

Después de eso, puede hacer lo que quiera, incluyendo 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 es indefinido. Y entonces, como sabemos, cualquier cosa puede suceder.

 30
Author: Bo Persson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-25 14:54:40

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 principal gancho para el comportamiento específico de la implementación.

 15
Author: Pete Becker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-25 19:41:00

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 el estándar describe indica que se comportará. Si contiene UB, el ejecutable puede hacer cualquier cosa.

Si el programa está mal formado sin necesidad de diagnóstico, el compilador puede hacer cualquier cosa. Puede producir una salida ejecutable, o no. Esa salida ejecutable puede hacer cualquier cosa. Podría diseñar un programa que parece 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 es exactamente un diagnóstico es la implementación definida. Se ha observado que imprimir una sola línea nueva en blanco, o un espacio, es un diagnóstico válido bajo la norma.

Que se consideraría una mala calidad de aplicació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 usted pide, producir un ejecutable que haga lo que quiera, o no producir ningún ejecutable.

La norma no distingue entre advertencias y errores.

Un programa mal formado que requiere un diagnóstico que imprime una advertencia, luego continúa compilando, no violar 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 sin necesidad de 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 describirse como una advertencia. También podría ser descrito como un error, pero el compilador debe producir un ejecutable, y el ejecutable debe hacer lo que el estándar manda.

 5
Author: Yakk - Adam Nevraumont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-25 20:06:47

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

Si un programa está mal formado, y que no es NDR, un diagnóstico debe ser producir. La norma no distingue entre advertencias o errores.

 2
Author: sp2danny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-25 15:01:50

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

Dicho esto, creo que ambas citas significan lo mismo. Un "programa mal formado" es aquel que no está construido de acuerdo con las reglas de sintaxis, reglas semánticas diagnosticables, y una regla de definición, del estándar (énfasis mío). Si una cierta semántica " no está permitida", eso solo significa que viola una regla semánticadiagnosticable de la lengua, y por lo tanto solo significa que está mal formada.

Se requiere que el compilador emita un diagnóstico para un programa que está mal formado. Después de eso, el compilador puede hacer lo que quiera. La norma no especifica ninguna condición bajo la cual deba fallar la compilación.

 2
Author: Oktalist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-25 15:17:43