Preocupaciones de seguridad sobre la evaluación de cortocircuito

Posible duplicado:
¿Los operadores booleanos de cortocircuito son obligatorios en C / C ++? ¿Y orden de evaluación?

AFAIK La evaluación de cortocircuito significa que una expresión booleana se evalúa solo hasta el punto en que podemos garantizar su resultado.

Este es un lenguaje común en perl donde podemos escribir cosas como: (is_ok () devuelve un valor distinto de cero en “OK”)

is_ok() || die "It's not OK!!\n"; 

en lugar de

 if ( ! is_ok() ) { die "It's not OK!!\n"; } 

Esto solo funciona porque el orden de evaluación siempre es de izquierda a derecha y eso garantiza que la statement más a la derecha solo se ejecute si la primera statement, si no es “falsa”.

En CI podemos hacer algo similar a:

 struct foo { int some_flag; } *ptr = 0; /* do some work that may change value of ptr */ if ( 0!=ptr && ptr->some_flag ) { /* do something */ } 

¿Es seguro usar este tipo de lenguaje?

¿O hay alguna posibilidad de que el comstackdor genere código que evalúe ptr->some_flag antes de asegurarse de que ptr no sea un puntero a cero? (Supongo que si no es nulo, apunta a alguna región de memoria válida).

Esta syntax es conveniente de usar porque guarda la escritura sin perder la legibilidad (en mi opinión de todos modos). Sin embargo, no estoy seguro de si es completamente seguro, por eso me gustaría aprender más sobre esto.

NB: si el comstackdor tiene un efecto en esto, estoy usando gcc 4.x

El orden de evaluación de los operadores de cortocircuito ( || y && ) está garantizado por la norma de izquierda a derecha (de lo contrario perderían parte de su utilidad).

§6.5.13 ¶4

A diferencia del operador & binario bitwise, el operador && garantiza la evaluación de izquierda a derecha; Hay un punto de secuencia después de la evaluación del primer operando. Si el primer operando se compara igual a 0 , el segundo operando no se evalúa.

§6.5.14 ¶4

A diferencia del bitwise | operador, el || el operador garantiza la evaluación de izquierda a derecha; Hay un punto de secuencia después de la evaluación del primer operando. Si el primer operando se compara de manera desigual con 0, el segundo operando no se evalúa.

¿O hay alguna posibilidad de que el comstackdor genere código que evalúe ptr-> some_flag antes de asegurarse de que ptr no sea un puntero a cero?

No, cero posibilidades. La norma garantiza que ptr->some_flag no se evaluará si el primer operando es falso.

6.5.13-4

A diferencia del operador y binario bitwise, el operador && garantiza la evaluación de izquierda a derecha; hay un punto de secuencia después de la evaluación del primer operando. Si el primer operando se compara igual a 0, el segundo operando no se evalúa .

 /* do some work that may change value of ptr */ if ( 0!=ptr && ptr->some_flag ) { /* do something */ } 

¿Es seguro usar este tipo de lenguaje?

Sí.

Es seguro en el ejemplo anterior, sin embargo, cualquiera que mantenga dicho código puede no darse cuenta de que existe una dependencia en el orden de evaluación y causar un error interesante.