tipos son problemas primaria preescolar niños los detectar definicion cuáles conducta como años adolescentes c++ language-lawyer undefined-behavior

c++ - son - tipos de problemas de conducta en niños



Diferencia entre comportamiento indefinido y mal formado, no se requiere mensaje de diagnóstico (2)

El estándar de C ++ viene con una sorprendente cantidad de definiciones para el comportamiento poco claro 1 que significa más o menos lo mismo con diferencias sutiles. Leyendo esta respuesta , noté la frase "el programa está mal formado; no se requiere diagnóstico" .

La implementación definida difiere del comportamiento no especificado en que la implementación en el primer caso debe documentar claramente lo que está haciendo (en el último caso, no es necesario), ambos están bien formados . El comportamiento no definido difiere de lo no especificado en que el programa es erróneo (1.3.13).
De lo contrario, todos tienen en común que el estándar no hace suposiciones o requisitos sobre lo que hará la implementación. Excepto 1.4 / 8, que establece que las implementaciones pueden tener extensiones que no alteran el comportamiento de los programas bien formados, pero que están mal formados de acuerdo con el estándar, y la implementación debe diagnosticar el uso de estos, pero luego puede continuar compilando y Ejecutando el programa mal formado.

Un programa mal formado se define de otra manera como no estar bien formado (¡genial!). Un programa bien formado , por otra parte, se define como uno que se adhiere a la sintaxis y las reglas semánticas diagnosticables. Lo que, en consecuencia, significaría que un programa mal formado es uno que rompe la sintaxis o las reglas semánticas (o ambas). En otras palabras, un programa mal formado en realidad no debería compilarse en absoluto (¿cómo se traduciría, por ejemplo, un programa con una sintaxis incorrecta de alguna manera significativa?).

Me inclino a pensar que la palabra errónea también implica que el compilador debería abortar la compilación con un mensaje de error (después de todo, erróneo sugiere que hay un error), pero la sección "Nota" en 1.3.13 permite explícitamente algo diferente, incluyendo ignorar silenciosamente el problema (y los compiladores demostrablemente no rompen la compilación debido a UB, la mayoría ni siquiera advierte de forma predeterminada).

Uno podría, además, creer que erróneos y mal formados son los mismos, pero el estándar no entra en detalles si ese es el caso o lo que se supone que significa la palabra.

Además, 1.4 establece que

una implementación conforme [...] aceptará y ejecutará correctamente un programa bien formado

y

Si un programa contiene una violación de una regla para la cual no se requiere ningún diagnóstico, no se [...] requiere ningún requisito en las implementaciones con respecto a ese programa.

En otras palabras, una implementación conforme debe aceptar un programa bien formado, pero también podría aceptar uno mal formado, e incluso sin una advertencia. Excepto, si el programa está mal formado porque utiliza una extensión .

El segundo párrafo sugiere que cualquier cosa en conjunto con "no se requiere diagnóstico" significa que no hay requisitos de la especificación, lo que significa que es mayormente equivalente a "comportamiento indefinido", excepto que no se menciona ningún error .

¿Cuál sería, por lo tanto, la intención detrás de usar un texto como "mal formado; no se requiere diagnóstico" ?

La presencia de "sin diagnóstico" sugeriría que es idéntico (o casi idéntico?) A un comportamiento indefinido. Además, dado que los comportamientos definidos por la implementación y no especificados se definen como bien formados , debe ser algo diferente .

Por otro lado, dado que un programa mal formado rompe las reglas de sintaxis / semántica, en realidad no debería compilarse. Sin embargo, lo que, junto con "no requiere diagnóstico", significaría que se permitiría que un compilador salga silenciosamente sin tanto aviso, y no podría encontrar un ejecutable posteriormente.

¿Hay una diferencia entre "mal formado, no se requiere diagnóstico" y "comportamiento indefinido", o es simplemente un sinónimo complicado para la misma cosa?

1 A falta de una mejor redacción para el colectivo de comportamientos.

El estándar no siempre es tan coherente como nos gustaría, ya que es un documento muy grande, escrito (en la práctica) por un número de personas diferentes y, a pesar de todas las pruebas de corrección que ocurren, las inconsistencias se resuelven. En el caso de comportamiento indefinido (y errores en general), creo que hay un problema adicional en que para la mayoría de las cosas más básicas (punteros, etc.), el estándar de C ++ inspira de C. Pero el estándar de C toma el punto para ver que todos los errores son un comportamiento indefinido, a menos que se indique lo contrario, cuando el estándar de C ++ intenta tomar el punto de vista de que todos los errores requieren un diagnóstico, a menos que se indique lo contrario. (Aunque todavía tienen que admitir el caso en el que el estándar omite especificar un comportamiento). Creo que esto explica gran parte de la inconsistencia en la redacción.

A nivel mundial, la inconsistencia es lamentable, pero en general, si el estándar dice que algo es erróneo o está mal formado, entonces se requiere un diagnóstico, a menos que el estándar diga que no, o que sea un comportamiento indefinido. En algo como " mal formado; no se requiere diagnóstico ", el " no requiere diagnóstico " es importante, porque de lo contrario, requeriría un diagnóstico. En cuanto a la diferencia entre "mal formado, no se requiere diagnóstico" y "comportamiento indefinido", no hay ninguno. El primero es probablemente más frecuente en los casos en que el código es incorrecto, el segundo es un problema de tiempo de ejecución, pero no es sistemático. (La especificación de la regla de una definición, claramente un problema de tiempo de compilación, termina con "entonces el comportamiento es indefinido".)


La forma en que debería ser es: las cosas que no están definidas no causan problemas siempre y cuando una ejecución particular de un programa no active el comportamiento indefinido. Por ejemplo, una desreferencia de puntero nulo solo arruina su día cuando se ejecuta su programa en particular (caracterizado por su entrada: I / O, funciones no deterministas como consultas de reloj, etc.) realmente lo ejecutan, pero se extienden hacia atrás, por lo que podrían mostrarse indefinidos Comportamiento incluso antes de alcanzar técnicamente la desreferencia. (Creo que esto es principalmente para permitir reordenamientos de código).

Mientras que la NDR mal formada es algo que la implementación debe diagnosticar durante la traducción, pero puede que no sea posible debido a diversas limitaciones técnicas o teóricas. Por ejemplo, la ODR requeriría la implementación para recopilar todas las definiciones de una entidad y compararlas; Pero eso es un drenaje masivo de recursos. Algunas cosas de NDR son incluso inviables computacionalmente. El comportamiento indefinido surge cuando la implementación no diagnostica inmediatamente estas cosas.

En la práctica, el comportamiento indefinido se aplica a algunos casos extraños que no son condiciones de tiempo de ejecución. Algunos problemas de preprocesador extraños desencadenan un comportamiento indefinido. Estos son raros porque no tienen una representación significativa en el programa compilado, por lo que no está claro qué los hará ejecutar.

Sin embargo, esta vista todavía le da una idea razonable de por qué hay dos términos.