c

Evaluación de cortocircuito y efectos secundarios



(3)

¿Se garantiza que las comparaciones posteriores (c == ALGO EN ESTE EJEMPLO) utilicen el valor establecido por canInitWithSomeValue (& c)?

Sí. Porque hay un punto de secuencia.

Entre la evaluación de los operandos izquierdo y derecho del && (AND lógico), || (OR lógico), y operadores de coma. Por ejemplo, en la expresión *p++ != 0 && *q++ != 0 , todos los efectos secundarios de la subexpresión * p ++! = 0 se completan antes de cualquier intento de acceso a q.

Un punto de secuencia define cualquier punto en la ejecución de un programa de computadora en el cual se garantiza que se habrán realizado todos los efectos secundarios de las evaluaciones anteriores, y aún no se han realizado efectos secundarios de evaluaciones posteriores.

Esta pregunta ya tiene una respuesta aquí:

Ok, estoy un poco avergonzado de hacer esta pregunta, pero solo quiero estar seguro ...

Se sabe que C utiliza la evaluación de cortocircuito en expresiones booleanas:

int c = 0; if (c && func(c)) { /* whatever... */ }

En ese ejemplo, func(c) no se llama porque c evalúa como 0 . Pero, ¿qué hay de un ejemplo más sofisticado donde los efectos secundarios de la comparación cambiarían la variable que se compara a continuación? Me gusta esto:

int c; /* this is not even initialized... */ if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ }

La función canInitWithSomeValue devuelve verdadero y cambia el valor en el puntero dado en caso de éxito. ¿Se garantiza que las comparaciones posteriores ( c == SOMETHING canInitWithSomeValue(&c) ) utilicen el valor establecido por canInitWithSomeValue(&c) ?

¿No importa qué tan pesadas sean las optimizaciones que usa el compilador?


La evaluación dentro de la condición compuesta de la sentencia if está estrictamente de izquierda a derecha. La única circunstancia en la que se optimizaría la segunda prueba sería si el compilador puede determinar con un 100% de certeza que la primera es idéntica a falsa.


Sí. Porque tanto && y || Los operadores también son algo llamados puntos de secuencia. Los últimos definen cuándo deben completarse los efectos secundarios de una operación anterior y los de la siguiente no deberían haber comenzado.