2010-10-03 12 views
9
void main(void) 
{ 
    int x,y,z; 
    x=y=z=1; 

    z = x && y && ++z;//is this fine? 
} 

Últimamente he comenzado a leer acerca de los puntos de secuencia pero no puedo determinar si la muestra de código anterior está bien o no. Sé que el operador && introduce un punto de secuencia, así que no estoy muy seguro del comportamiento de la expresión z = x & & y & & ++ z. Alguien por favor dime la respuesta correcta.expresión complicada que implica AND lógico (&&)

+4

tipo devuelto de 'main()' 'debe ser int' en C y en C++. –

Respuesta

-2

Sí, compilará.

Pero si usted está planteando errores lógicos:

1) el operador && introduce un punto de la secuencia, ya que podría terminar la evaluación de la expresión cuando se sabe con certeza el resultado final (en este caso un valor 0 puede finalizar la evaluación), por lo que ni siquiera alcanzará la parte ++z si x o y es cero.

2) porque el operador && es lógico, el resultado siempre será 0 o 1, y dudo que esto sea lo que usted quería.

6

En C++ 03.

void main(void) 
{ 
    int x,y,z; 
    x=y=z=1;         // Seq1 at ; 

    z = x && y && ++z;//is this fine?   // Seq2 at ; 
} 

NB: Observe que hay puntos de secuencia en el operador & & pero luego los que no son relevantes en este ejemplo.

¡Fino !. En general, puede ser o no ser. Depende de los valores de x y y. En su caso específico, no está bien. Este código tiene el potencial de tener algo llamado undefined behavior.

Si z ++ es evaluado (como en su ejemplo porque x e y son 1), entonces el escalar 'z' variable se modificó más de una vez en la expresión entre dos secuencia de puntos de Sec1 y Sec2 (ver abajo). Es importante tener en cuenta que el operador de asignación no introduce ningún punto de secuencia.

$ 5/4- "Excepto donde se indique, el orden de la evaluación de los operandos de operadores individuales y subexpresiones de expresiones individuales, y el orden en que efectos secundarios tienen lugar, es unspecified.53) Entre el anterior y el próximo punto de secuencia de un objeto escalar tendrá su valor almacenado modificado como máximo una vez por la evaluación de una expresión. Además, el valor previa se acceder sólo a de termine el valor para ser almacenado. Los requisitos de este párrafo se cumplirán para cada orden permitida de las subexpresiones de una expresión completa; de lo contrario el comportamiento no está definido."

En C++ 0x

actualizará una vez yo mismo entiendo los detalles de la discusión mencionada por @litb.Por ahora, solo lo estoy cerrando

En C++ 0X, sin embargo, como entiendo, no existe el concepto de puntos de secuencia. Esta expresión está bien y no invoca un comportamiento indefinido. Esto se debe a que el efecto de ++ en 'z' se secuencia antes del efecto secundario de la asignación en 'z'.

$ 1,9/15- "Excepto donde se indique, evaluaciones de los operandos de operadores individuales y de subexpresiones de expresiones individuales son unsequenced [Nota:. En una expresión que se evalúa más de una vez durante la ejecución de un programa, unsequenced y indeterminadamente evaluaciones secuenciados de sus subexpresiones no debe efectuarse la consistentemente en diferentes evaluaciones. cálculos -end nota] el valor de los operandos de un operador son secuenciados antes del cómputo del valor del resultado del operador. Si un efecto lado en un objeto de escalar es unsequenced relativa a cualquiera otro efecto lado en el mismo objeto escalar o un cálculo de valor usando el valor del mismo objeto escalar, el comportamiento es indefinido.

$ 3,9/9 - "tipos aritméticas (3.9.1), tipos de enumeración, los tipos de puntero, puntero a tipos miembros (3.9.2), std :: nullptr_t, y CV-calificados versiones de estos tipos (3.9.3) son colectivamente llamados tipos escalares ".

Tenga en cuenta que en la expresión 'z = z ++;' donde z es una variable escalar, los efectos secundarios en 'z' debidos al operador de asignación y al operador postfix ++ no se siguen (ninguno de ellos se secuencia antes que el otro).

Gracias @Prasoon para dar insumos valiosos para refinar este post de versión original

+2

@Prasoon Saurav: ¿dónde estás? – Chubsdad

+2

@Chubsdad: el comportamiento no estaría definido según los valores de 'x' y' y'. Pero tenemos 'x = 1' y' y = 1' así que la evaluación de '++ z' está garantizada, por lo tanto, el comportamiento sería indefinido porque' z' se está modificando más de una vez entre dos puntos de secuencia [asignación y preincremento modifique 'z' dos veces sin ningún punto de secuencia intermedio]. Tenga en cuenta que su publicación contiene una cita del borrador de C++ 0x. En C++ 0x 'i = ++ i' es un comportamiento bien definido. –

+0

Votó su respuesta ahora. :) –

2

Una forma sencilla de saber si esa línea está bien o no, es dejar que el compilador de comprobar que. Por ejemplo, gcc tiene the -Wsequence-point option (habilitado por -Wall) para verificar si hay un comportamiento indefinido debido a la falta de puntos de secuencia.

Su programa

int main(void) 
{ 
    int x,y,z; 
    x=y=z=1; 

    z = x && y && ++z;/*is this fine?*/ 

    return 0; 
} 

produce esta advertencia:

 
x.c: In function 'main': 
x.c:6:5: warning: operation on 'z' may be undefined 
+0

Es frustrante que gcc requiera una opción especial para producir advertencias sobre esto en lugar de solo generar 'movb $ 0,0' o equivalente para dicho código. –

Cuestiones relacionadas