c - para - g++ windows
¿C hace la diferencia entre compilar y ejecutar un programa? (3)
¿es conforme si una implementación lo rechaza en tiempo de compilación?
Puede o no. El estándar C dice al respecto en la sección §3.4.3:
C11: 3.4.3 comportamiento indefinido
comportamiento, al usar una construcción de programa errónea o no portable o datos erróneos, para los cuales esta Norma Internacional no impone requisitos
NOTA El comportamiento indefinido varía desde ignorar completamente la situación con resultados impredecibles, hasta comportarse durante la traducción o la ejecución del programa de una manera documentada característica del entorno (con o sin la emisión de un mensaje de diagnóstico), hasta terminar una traducción o ejecución (con el emisión de un mensaje de diagnóstico) .
Así que responda a su pregunta: ¿Puede causar un desbordamiento del búfer en el compilador?
Sí puede.
Si una evaluación de una expresión provoca un comportamiento indefinido en C, y la expresión siempre se evalúa cuando se ejecuta el programa (por ejemplo, si aparece al principio de main
), ¿es conforme si una implementación lo rechaza en tiempo de compilación ? ¿Hay alguna diferencia en C entre compilar / traducir un programa y ejecutarlo?
Sé que hay intérpretes para C. ¿Cómo los maneja el estándar C con respecto a esta diferencia?
Ejemplo (lectura local no inicializada)
int main() { int i; return i; }
Al ejecutarlo, en cualquier etapa de la ejecución (incluso antes de que se llame a main
), el programa puede hacer algo gracioso. Pero, ¿puede suceder algo gracioso cuando ni siquiera hemos intentado ejecutarlo? ¿Puede causar un desbordamiento del búfer en el compilador?
De un proyecto C11:
3.4.3 comportamiento indefinido
comportamiento, al usar una construcción de programa errónea o no portable o datos erróneos, para los cuales esta Norma Internacional no impone requisitos
NOTA El comportamiento indefinido varía desde ignorar completamente la situación con resultados impredecibles, hasta comportarse durante la traducción o la ejecución del programa de una manera documentada característica del entorno (con o sin la emisión de un mensaje de diagnóstico), hasta terminar una traducción o ejecución (con el emisión de un mensaje de diagnóstico).
La terminación de la traducción se menciona como una posible consecuencia del comportamiento indefinido en la nota (no normativa), por lo que los efectos del tiempo de compilación claramente no están destinados a ser excluidos. La parte normativa ciertamente lo permite, permite cualquier cosa. Entonces el compilador conforme puede terminar la traducción si detecta un comportamiento indefinido durante la compilación.
Además, en conformidad de $ 4 :
Si se infringe un requisito de '''' debe '''' o '''' no se '''' que aparece fuera de una restricción o restricción de tiempo de ejecución, el comportamiento no está definido. El comportamiento indefinido está indicado de otra manera en esta Norma Internacional por las palabras "comportamiento indefinido" u omisión de cualquier definición explícita de comportamiento. No hay diferencia en el énfasis entre estos tres; todos describen "comportamiento indefinido".
No se hace ninguna distinción ni en la definición normativa ni en la descripción de conformidad entre "tiempo de traducción" y "tiempo de ejecución". No se diferencia entre las diferentes "variedades" de comportamiento indefinido.
Además, el Informe de defectos n. ° 109 señalado por ouah en ¿Puede el código que nunca se ejecutará invocar un comportamiento indefinido? tiene esto en su respuesta:
[...] Si una expresión cuya evaluación daría como resultado un comportamiento indefinido aparece en un contexto donde se requiere una expresión constante, el programa que lo contiene no es estrictamente conforme. Además, si cada posible ejecución de un programa determinado daría lugar a un comportamiento indefinido, el programa dado no se ajusta estrictamente.
Una implementación conforme no debe dejar de traducir un programa estrictamente conforme simplemente porque una posible ejecución de ese programa daría como resultado un comportamiento indefinido. [...]
Esto indicaría que un compilador no puede fallar una traducción si no puede determinar estáticamente que todas las rutas conducen a un comportamiento indefinido.
En el estándar C11, §3.7.1 se establece, bajo la definición del término comportamiento indefinido :
Comportamiento indefinido : comportamiento, al usar una construcción de programa errónea o no portable o datos erróneos, para los cuales esta Norma Internacional no impone requisitos.
2 NOTA El comportamiento indefinido varía desde ignorar completamente la situación con resultados impredecibles, hasta comportarse durante la traducción o la ejecución del programa de una manera documentada característica del entorno (con o sin la emisión de un mensaje de diagnóstico), hasta terminar una traducción o ejecución (con la emisión de un mensaje de diagnóstico) .
Así que supongo que se te permite rechazar estáticamente un programa que contiene un comportamiento indefinido, incluso si es válido.