Últimamente, he visto muchas preguntas sobre el resultado de algunas sentencias de código locamente pero sintácticamente permitidas como i = ++i + 1
y i=(i,i++,i)+1;
. Francamente, hablando de forma realista, casi nadie escribe un código de ese tipo en la programación real. Para ser sincero, nunca he encontrado un código de este tipo en mi experiencia profesional. Así que termino omitiendo tales preguntas aquí en SO. Pero últimamente el volumen total de preguntas de ese tipo me hace pensar si me estoy perdiendo una teoría importante salteándome tales Q. Deduzco que las Q de este tipo giran en torno al Sequence points
. Casi no sé nada sobre los puntos de secuencia para ser franco y me pregunto si no saberlo es una desventaja de alguna manera. Entonces, ¿alguien puede explicar la teoría/concepto de Sequence points
o, si es posible, señalar un recurso que explique el concepto? Además, ¿vale la pena invertir tiempo en conocer este concepto/teoría?Una explicación acerca de los puntos de secuencia
Respuesta
La respuesta más simple que puedo pensar es:
C++ se define en términos de una máquina abstracta. La salida de un programa ejecutado en la máquina abstracta se define ÚNICAMENTE en términos del orden en que se realizan los "efectos secundarios". Y los efectos secundarios se definen como llamadas a las funciones de la biblioteca IO, y los cambios a las variables marcadas como volátiles.
Los compiladores de C++ pueden hacer lo que deseen internamente para optimizar el código, pero no pueden cambiar el orden de las escrituras en variables volátiles y llamadas io.
Los puntos de secuencia definen los latidos del programa c/C++: los efectos secundarios antes de que el punto de secuencia sea "completo" y los efectos secundarios después del punto de secuencia aún no se han producido. Pero, efectos secundarios (o, código que puede efectuar un efecto secundario indirectamente (dentro un punto de secuencia puede ser reordenado.
razón por la cual comprensión es importante. Sin esa comprensión, su comprensión fundamental de lo que es una programa en C++ es (y cómo podría optimizarse mediante un compilador agresivo) es errónea.
Ver http://en.wikipedia.org/wiki/Sequence_point.
Es un concepto bastante simple, por lo que no es necesario invertir mucho tiempo :)
No estoy de acuerdo con que sea un concepto simple, por lo que he visto en los hilos y las explicaciones, parece ser un concepto bastante difícil de entender, ¡o quizás, me parece difícil! –
Mira el artículo de Wikipedia. La primera oración básicamente define el concepto. Hay muchos detalles sobre dónde ocurre la secuencia en C++, pero no se trata del concepto. –
Vale la pena saber que existen los puntos de secuencia porque si usted no sabe acerca de ellos puede escribir fácilmente el código que parece funcionar bien en las pruebas, pero en realidad no está definido y puede fallar cuando lo ejecuta en otra computadora o con diferentes opciones de compilación. En particular, si escribe, por ejemplo, x++
como parte de una expresión más grande que también incluye x
, puede tener problemas fácilmente.
No creo que sea necesario aprender todas las reglas por completo, pero debe saber cuándo debe verificar la especificación, o quizás mejor, cuándo reescribir el código para que no sea confiando en las reglas de puntos de secuencia si un diseño más simple funcionaría también.
Sé que es bastante subjetivo preguntar, pero saber cuánto es saber lo suficiente? ¿Cuáles son las reglas que uno DEBE/ATLEAST conocer? –
int n,n_squared;
for(n=n_squared=0;n<100;n_squared+=n+ ++n)
printf("%i squared might or might not be %i\n",n,n_squared);
... no siempre hace lo que piensa que va a hacer. Esto puede hacer que la depuración dolorosa. La razón se ++ ++ recupera, modifica y almacena el valor de n, que podría ser anterior o posterior a la recuperación de n. Por lo tanto, el valor de n_squared no está claramente definido después de la primera iteración. Los puntos de secuencia garantizan que las subexpresiones se evalúan en orden.
Los detalles técnicos exactos de los puntos de secuencia pueden ser peludos, sí.Pero siguiendo estas directrices resuelve casi todas las cuestiones prácticas:
- Si una expresión modifica un valor, tiene que haber un punto de secuencia entre la modificación y cualquier otra uso de ese valor.
- Si no está seguro de si dos usos de un valor están separados por un punto de secuencia o no, divida su código en más instrucciones.
Aquí "modificación" incluye las operaciones de asignación en el valor de la izquierda en =
, +=
, etc., y también los ++x
, x++
, --x
, y x--
sintaxis. (Por lo general, estas expresiones de incremento/decremento donde algunas personas tratan de ser inteligente y terminan metiéndose en problemas.)
Afortunadamente, hay puntos de secuencia en la mayoría de los lugares "esperados":
- Al fin de cada declaración o declaración
- Al comienzo y al final de cada llamada a la función.
- En los operadores integrados
&&
y||
. - En el
?
en una expresión ternaria. - En el operador de coma incorporado
,
. (Más comúnmente visto en condiciones, por ejemplofor (a=0, b=0; a<m && b<n; ++a, ++b)
.) Una coma que separa los argumentos de la función es no el operador de coma y es no un punto de secuencia.
sobrecargado operator&&
, operator||
y operator,
no causan puntos de secuencia. Las posibles sorpresas de ese hecho es una de las razones por las que se suele desalentar la sobrecarga.
- 1. Campos de bits y puntos de secuencia
- 2. Otra pregunta más relacionada con los puntos de secuencia
- 3. Puntos de secuencia, condicionales y optimizaciones
- 4. Explicación del operador de dos puntos en ": $ {foo = value}"
- 5. ¿Cuáles son los puntos importantes acerca de las funciones hash criptográficas?
- 6. Una pregunta acerca de los tutoriales de Interbloqueo del Sol
- 7. Confundido acerca de los parámetros de LINQ
- 8. ternarias de operador y la secuencia de puntos en C
- 9. preguntas acerca de una interfaz
- 10. Confundido acerca de cómo instalar los complementos de Rails
- 11. Explicación de NHibernate HiLo
- 12. ¿La mejor explicación de los bloques Ruby?
- 13. Acerca de los punteros en Objective-C
- 14. explicación acerca de las instrucciones push ebp y pop ebp en el ensamblado
- 15. Permitir solo números y puntos en la secuencia de comandos
- 16. suma de los números que hacen una secuencia de
- 17. F #: ¿Cómo dividir una secuencia en una secuencia de secuencias
- 18. ¿Una explicación simple de Rings en Riak?
- 19. Explicación de los espacios de nombres de Python
- 20. GAS: Explicación de .cfi_def_cfa_offset
- 21. R: eliminación de los últimos tres puntos de una cadena
- 22. Cómo encontrar los puntos de borde de una forma particular
- 23. obteniendo los límites de una lista de puntos x, y
- 24. pregunta acerca de los especificadores de formato de impresión incompatibles
- 25. ¿Podría obtener una explicación básica de CATransform3DIdentity?
- 26. cómo calcular los puntos de control para una ruta sin problemas dado un conjunto de puntos?
- 27. Explicación de contribute_to_class
- 28. La manera más fácil de dibujar una secuencia de puntos en WPF desde el código
- 29. Acerca de Spring BeanFactory
- 30. Algoritmo FASTA Explicación
El artículo de Steve Summit [aquí] (http://c-faq.com/expr/seqpoints.html) sería útil. –
Lea la sección 1.9 y la introducción a la sección 5 (es decir, antes de 5.1). –