how from diferencias code c++ c

c++ - from - extern c



¿Qué es el comportamiento indeterminado en C++? ¿En qué se diferencia del comportamiento indefinido? (3)

¿Cuál es la diferencia entre un comportamiento indeterminado y un comportamiento indefinido en C ++? ¿Es esta clasificación válida para los códigos C también?


Creo que el estándar menciona un comportamiento indefinido y un valor indeterminado. Entonces uno es sobre el comportamiento y otro sobre los valores.

Estos dos son algo ortogonales, por ejemplo, el comportamiento todavía puede estar bien definido en presencia de valores indeterminados.


Las siguientes observaciones se basan en el estándar C, ISO-9899 , en lugar del estándar C ++, pero los significados son básicamente los mismos (vea las secciones 3.4 y 4 del estándar C; vea también el estándar C ++, ISO-14882 , sección 1.3 ; el último documento no define "valor no especificado" como tal, pero usa esa frase más adelante con el significado obvio). Los documentos de estándares oficiales no son gratuitos (de hecho, son caros), pero los enlaces de arriba son a las páginas del comité e incluyen ''borradores'' gratuitos del estándar, que puede considerar esencialmente equivalentes al texto estándar finalizado.

Los términos describen una escalera de vaguedad.

Entonces, dirigiéndose hacia abajo ....

La mayoría de las veces, el estándar define lo que debería suceder en un caso particular: si escribe c=a+b y a y b son int , entonces c es su suma (módulo, algunos detalles). Esto, por supuesto, es el punto de una norma.

El comportamiento definido por la implementación es donde el estándar enumera dos o más cosas que pueden suceder en un caso particular; no prescribe cuál es el preferido, pero exige que la implementación (el compilador real que analiza la C) haga una elección entre las alternativas, haga lo mismo de manera consistente, y que la implementación deba documentar la elección que hace . Por ejemplo, si un solo archivo puede abrirse mediante múltiples procesos está definido por la implementación.

El comportamiento no especificado es donde el estándar enumera un par de alternativas, cada una de las cuales es, por lo tanto, conforme con el estándar, pero no va más allá. Una implementación debe elegir una de las alternativas a elegir en un caso particular, pero no tiene que hacer lo mismo cada vez, y no tiene que comprometerse en la documentación de la elección que hará. Por ejemplo, los bits de relleno en una struct no están especificados.

El comportamiento indefinido es el caso más extremo. Aquí, todas las apuestas están apagadas. Si el compilador, o el programa que genera, tiene un comportamiento indefinido , puede hacer cualquier cosa: puede codificar la memoria, corromper la pila, HCF o, en el caso extremo estándar, hacer que los demonios salgan volando de tu nariz. Pero en su mayoría simplemente se estrellará. Y todos estos comportamientos son conformes con el estándar. Por ejemplo, si una variable se declara tanto static int i; e int i; en el mismo ámbito, o si escribe #include <''my file''.h> , el efecto no está definido.

Hay definiciones análogas para ''valor''.

Un valor no especificado es un valor válido, pero el estándar no dice qué es. Por lo tanto, el estándar podría decir que una función dada devuelve un valor no especificado. Puede almacenar ese valor y mirarlo si lo desea, sin causar un error, pero no significa nada, y la función podría devolver un valor diferente la próxima vez, dependiendo de la fase de la luna.

Un valor definido por la implementación es como el comportamiento definido por la implementación. Como no especificado , es un valor válido, pero la documentación de la implementación debe comprometerse con lo que se devolverá y hacer lo mismo cada vez.

Un valor indeterminado aún más no especificado que no especificado . Es un valor no especificado o una representación de captura . Una representación de trampa es un lenguaje estándar para algún valor mágico que, si intenta asignarlo a cualquier cosa, se traduce en un comportamiento indefinido. Esto no tendría que ser un valor real; Probablemente la mejor manera de pensarlo es "si C tuviera excepciones, una representación de trampa sería una excepción". Por ejemplo, si declara int i; en un bloque, sin una inicialización, el valor inicial de la variable i es indeterminado , lo que significa que si intenta asignar esto a otra cosa antes de inicializarla, el comportamiento no está definido, y el compilador tiene derecho a probar dichos demonios. Truco de la nariz. Por supuesto, en la mayoría de los casos, el compilador hará algo menos dramático / divertido, como inicializarlo en 0 o algún otro valor válido aleatorio, pero no importa lo que haga, no tiene derecho a objetar.

El punto de toda esta imprecisión es dar la máxima libertad a los escritores compiladores. Eso es bueno para los escritores de compiladores (y es una de las razones por las que es razonablemente fácil hacer que un compilador de C se ejecute en una gama tan amplia de plataformas), pero hace que las cosas sean más interesantes que divertidas para los usuarios pobres.

Edición 1 : para aclarar valores indeterminados.

Edición 2 : para incluir un enlace a la norma de C ++, y tenga en cuenta que los borradores del comité son esencialmente equivalentes a la norma final, pero gratuitos.


EDICIÓN 1: Los últimos borradores de C11 y C ++ 11 están disponibles en línea aquí: C11 draft N1570 y C ++ 11 draft n3242 si no tiene una copia de los estándares finales y es maravilloso su aspecto. (Se han realizado otros ajustes en la apariencia del texto y algunas ediciones de texto / gramática).

EDIT 2: Se corrigió que todas las apariciones de "comportamiento" fueran "comportamiento" para que coincidieran con el estándar.

Al buscar los estándares C ++ 11 y C11, no hay coincidencias para una regla indeterminada o una regla no definida . Hay términos como valor indeterminado , secuenciado indeterminado , indeterminado no inicializado , etc.

Si hablar de trampas y excepciones parece extraño en la respuesta de Norman Gray, sepa que esos términos reflejan las definiciones relevantes en la Sección 3 en el estándar C11 .

C ++ se basa en las definiciones de C. Se pueden encontrar muchas definiciones útiles sobre tipos de comportamiento en la Sección 3 de C11 (en C11). Por ejemplo, el valor indeterminado se define en 3.19.2. Tenga en cuenta que la Sección 2 (Referencias normativas) de C11 proporciona otras fuentes para la interpretación de la terminología adicional y la Sección 4 define cuándo ocurren casos como un comportamiento indefinido como resultado del incumplimiento de la norma.

La sección 3.4 de C11 define el comportamiento , 3.4.1 define el comportamiento definido por la implementación , 3.4.2 define el comportamiento específico de la localidad , 3.4.3 define el comportamiento indefinido , 3.4.4 define el comportamiento no especificado . Para el valor (Sección 3.19), hay un valor definido por la implementación, un valor indeterminado y un valor no especificado .

En términos generales, el término indeterminado se refiere a un estado no especificado / desconocido que por sí solo no produce un comportamiento indefinido . Por ejemplo, este código C ++ implica un valor indeterminado: {int x = x; }. (Este es en realidad un ejemplo en el estándar C ++ 11). Aquí x se define como un entero primero, pero en ese punto no tiene un valor bien definido, luego se inicializa a lo que sea (indeterminado / desconocido) valor que tiene!

El término conocido comportamiento indefinido se define en 3.4.3 en C11 y se refiere a cualquier situación de un

Construcción de programas no portables o erróneos o de datos erróneos, para los cuales esta Norma Internacional no impone requisitos

En otras palabras, el comportamiento indefinido es un error (en lógica o estado) y se desconoce lo que ocurra a continuación. Entonces, uno podría hacer una regla de [comportamiento] indefinido que diga: ¡evite el comportamiento indefinido al escribir código C / C ++! :-)

Una regla de [comportamiento] indeterminado sería indicar: evite escribir código indeterminado a menos que sea necesario y no afecte la corrección o portabilidad del programa. Por lo tanto, a diferencia del comportamiento indefinido, el comportamiento indeterminado no necesariamente implica que el código / los datos sean erróneos, sin embargo, su uso posterior puede ser erróneo o no, por lo que se debe tener cuidado para garantizar que se mantiene la corrección del programa.

Otros términos como secuenciación indeterminada se encuentran en el texto del cuerpo (por ejemplo, C11 5.1.2.3 párrafo 3; C ++ 11, sección 1.9 párrafo 13; es decir, en [ejecución de intro]). (Como puede adivinar, se refiere a un orden no especificado de pasos operativos).

En mi opinión, si uno está interesado en todos estos matices, es imprescindible adquirir los estándares C ++ 11 y C11. Esto le permitirá a uno explorar el nivel de detalle deseado que se necesita con definiciones, etc. Si no tiene tales enlaces, los enlaces proporcionados en este documento lo ayudarán a explorar dichos estándares con el último borrador publicado C11 y C ++ 11.