2010-07-21 11 views
7

¿Se permite implementar C++ conforme a las normas para implementar algún comportamiento que se dice que está definido en la implementación en el estándar de tal manera que es diferente entre diferentes ejecuciones del mismo programa compilado una vez con los mismos datos de entrada?¿Se requiere un comportamiento definido en la implementación para ser consistente entre las ejecuciones en C++?

Por ejemplo, ¿se permite que una implementación diga "el comportamiento es esto los fines de semana y de lo contrario" e implemente el comportamiento de acuerdo con dicha afirmación? significa comportamiento definido

+2

¿tiene un ejemplo concreto en mente? alternativamente tomaría "implementación definida" como exactamente eso y si el implementador hace una garantía de consistencia, entonces espera consistencia, de lo contrario, todas las apuestas están desactivadas – msw

+3

GCC solía ser mucho más genial con un comportamiento indefinido: http: //en.wikipedia .org/wiki/Undefined_behavior # Compiler_easter_eggs – sarnold

Respuesta

1

Implementación

especi Comportamiento fi cada en cada implementación documentos cómo se hace la elección

Es obligatoria para los autores de compiladores para documentar el comportamiento de una programación en particular construir para una implementación particular.

..... de tal manera que es diferente entre diferentes ejecuciones del mismo programa compilado una vez con los mismos datos de entrada?

Nopes!

Por ejemplo, ¿se permite que una implementación diga "el comportamiento es esto los fines de semana y de lo contrario" e implemente el comportamiento de acuerdo con dicha afirmación?

No estoy seguro, pero creo que la respuesta es no.

+4

No veo por qué esto no está permitido. El estándar dice "cómo se realiza la elección", no "cuál es la elección que se hace". – sharptooth

+3

Tal como lo veo, la definición de comportamiento definido por implementación dado no excluye la posibilidad de diferencias de ejecución a ejecución, siempre que documente exactamente cuándo ocurre cada caso y exactamente qué sucede para cada uno. –

+1

@sharptooth: He editado mi respuesta, pero estoy casi seguro de que la respuesta a su primera pregunta es NO. Por ejemplo, si se considera 'sizeof (int)', está garantizado (ya que la implementación ha documentado el comportamiento) como una solución para una implementación en particular. .... Estoy un poco confundido por 'e implemento un comportamiento de acuerdo con dicha declaración?' –

0

rand(3) en <stdlib.h> se puede llamar desde C++, no estoy seguro de qué parte de la biblioteca C se incluye en "C++ estándar", pero seguramente hay algún mecanismo conforme a las normas para generar números aleatorios.

time(3) en <time.h> devuelve la hora actual; misma historia con C++ y llamando a la biblioteca C.

+1

¿cómo es esto relevante para la pregunta? – Naveen

+0

¿Están 'rand()' o 'time()' etiquetados como implementados? Solo puedo suponer que lo son, y de ser así, ciertamente serían un contraejemplo. Bueno, a menos que considere la hora actual y/o el estado RNG del sistema como parte de la entrada. –

+0

@naveen, supuse que 'rand()' se especifica en el estándar, pero los detalles están definidos por la implementación. Tengo problemas para verificar esta suposición. – sarnold

6

Por supuesto, si la implementación documenta exactamente cuando el comportamiento cambia con diferentes ejecuciones, está bien. Observe que el comportamiento definido por la implementación es parte de los parámetros de la máquina abstracta:

Las descripciones semánticas en esta Norma Internacional definen un parametrizada no determinista máquina abstracta .

Ciertos aspectos y operaciones de la máquina abstracta se describen en esta Norma Internacional como definidos por la implementación (por ejemplo, sizeof (int)). Estos constituyen los parámetros de la máquina abstracta. Cada implementación debe incluir documentación que describa sus características y comportamiento en estos aspectos. Dicha documentación debe definir la instancia de la máquina abstracta que corresponde a esa implementación (a la que se hace referencia como la "instancia correspondiente" a continuación).

Esto no permite cambiar el comportamiento en una sola ejecución del compilador.Pero entre las diferentes ejecuciones del compilador, el compilador puede usar una máquina abstracta diferente correspondiente que difiere por diferentes valores definidos de implementación, de acuerdo con lo que definió la implementación. Los parámetros de línea de comando como -Wall (que cambia el conjunto de mensajes de diagnóstico definidos por la implementación) son el ejemplo más común de esto. Esta es una diferencia para el comportamiento no especificado además de los requisitos de documentación. El comportamiento no especificado es mucho menos restrictivo:

Algunos otros aspectos y operaciones de la máquina abstracta se describen en esta Norma Internacional como no especificados (por ejemplo, orden de evaluación de argumentos para una función). Donde sea posible, este Estándar Internacional define un conjunto de comportamientos permitidos. Estos definen los aspectos no deterministas de la máquina abstracta. Una instancia de la máquina abstracta puede así tener más de una secuencia de ejecución posible para un programa dado y una entrada dada.

+0

'... define una máquina abstracta no determinista parametrizada. 'Como la máquina abstracta no es determinista, ¿cómo es necesario que un comportamiento sea consistente en una sola ejecución del compilador? –

+0

@Prasoon, solo algunas rutas, aquellas donde el comportamiento no está especificado, introducen el no determinismo. Por ejemplo, la expresión regular 'z (a | b)' puede ser expresada por una máquina de estado finito no determinista (NFA) que coincida con 'a' o' b' al final de la entrada. Pero aún así, coincide sistemáticamente con 'z' al comienzo de la entrada :) Ahora, para el comportamiento definido por la implementación, si los parámetros (por ejemplo, 'z' al inicio) cambiarían, se obtendría una máquina abstracta correspondiente diferente resultante. Ya no tendrías una sola implementación para traducir el código fuente, sino dos. :) –

+0

¡¡Ah !! Y la pregunta de sharptooth menciona que los datos de entrada son los 'mismos' ... ¡Uf! gracias Johannes :) –

1

IIRC, se requiere que el sistema() exista, pero se da un comportamiento definido de implementación. Algo así como el sistema ("ls | grep foo") naturalmente tendrá diferentes efectos en función de si su sistema puede ejecutar algo llamado ls, que puede variar entre ejecuciones. E incluso en una máquina UNIX bastante normal donde ls y grep hacen lo que cabría esperar y no se eliminan, el resultado dependerá de la existencia de un archivo con foo en el nombre, que sin dudas podrá variar a lo largo del tiempo. hora, y desde donde se ejecuta el programa, etc. Simplemente depende de dónde dibuje la línea de "los mismos datos de entrada". Si la máquina está en un estado perfectamente idéntico, entonces puede esperar un comportamiento idéntico, pero no habrá dos carreras que involucren a una máquina verdaderamente en un estado pedantemente idéntico. (Incluso la temperatura de la CPU en máquinas que, por lo demás, serían perfectamente idénticas, podría provocar un comportamiento de estrangulamiento que altere al ganador de alguna condición de carrera, lo que produce un comportamiento diferente del programa).

3

Un ejemplo en el que puedo pensar es si el programa usa representación endian grande o pequeña para números. Creo que esto ciertamente contaría como comportamiento definido de implementación.

En algunos chips, por ejemplo ciertos chips ARM es posible cambiar los modos en tiempo de ejecución así que puede querer un compilador que podría producir un programa que se ejecutaría en cualquier modo lo que significa que tiene un comportamiento definido de implementación que podría ser potencialmente diferente en cada ejecución dependiendo de la configuración externa.

De manera similar, supongo que podría escribir un compilador que produjera tanto 32 como 64 bits compilados del mismo programa, y ​​el modo que ejecutara podría determinarse en tiempo de ejecución. Una vez más, la documentación debería decir que las entradas eran de 32 bits o de 64 bits, dependiendo de cómo lo haya ejecutado.

Para ser honesto, no puedo ver a nadie haciendo estas cosas, pero ambos suenan vagamente plausibles ejemplos de lo que estaba pidiendo y no puedo ver por qué no serían legales bajo el estándar mientras ya que la documentación documentó adecuadamente la naturaleza del comportamiento dependiente del sistema.

+0

+1, en MacOSX los binarios universales contienen una versión de 32 y 64 bits (en las últimas versiones de MacOS X que tienen soporte de 64 bits) y usted puede elegir en el momento del lanzamiento qué versión desea ejecutar. Los binarios incluso pueden contener código para una arquitectura completamente diferente como PowerPC. Y en caso de que te lo preguntes, es útil.Hay algunos complementos de safari que no se pueden ejecutar en 64 bits, por lo que puede iniciar una sesión de safari en 32 bits cuando los necesite. –

+0

Ah, qué bueno, no sabía que MaxOSX hizo esto :) – jcoder

1

Las garantías son las que el compilador ha documentado. Los diferentes indicadores del compilador o el estado diferente de la computadora en el momento de la compilación pueden afectar la forma en que el compilador/optimizador procesa su programa y eso puede tener un efecto en el resultado. Con los indicadores del compilador que tienen el mayor impacto (el mismo compilador se puede usar para generar programas de 32 y 64 bits en un entorno de 64 bits, en las dos ejecuciones los requisitos de alineación pueden diferir).

Puede esperar que en la mayoría de los casos el implementador proporcione algunas garantías básicas sobre el comportamiento de la implementación y el programa que genera para un conjunto dado de parámetros de compilador/enlazador. Incluso si la carga del sistema puede afectar cuánto puede funcionar el optimizador en su programa (algunos optimizadores tendrán un tiempo limitado) eso no debería cambiar el comportamiento esperado.

Tenga en cuenta que si bien no hay garantía, sería difícil comercializar un compilador que produce código con diferentes comportamientos dependiendo de parámetros no relacionados como la posición de la luna con respecto a las estrellas.

Cuestiones relacionadas