rango - series en c++ ejemplos
¿Por qué la expresión a=a+b-(b=a) da una advertencia de punto de secuencia en c++? (4)
A continuación se muestra el código de prueba:
int main()
{
int a = 3;
int b = 4;
a = a + b - (b = a);
cout << "a :" << a << " " << "b :" << b << "/n";
return 0;
}
Compilar esto da la siguiente advertencia:
> $ g++ -Wall -o test test.cpp test.cpp: In function ‘int main()’:
> test.cpp:11:21: warning: operation on ‘b’ may be undefined
> [-Wsequence-point]
¿Por qué la operación puede ser indefinida?
Según mi entendimiento, primero se debe evaluar la subexpresión (b = a)
debido a la mayor precedencia de (), estableciendo así b = a. Luego, dado que ''+'' y ''-'' tienen la misma prioridad, la expresión se evaluará de manera asociativa a la izquierda. Por lo tanto, a + b
debe evaluar a continuación, y finalmente el resultado de (b = a)
debe restar de a + b
. No puedo ver ninguna regla de punto de secuencia violada aquí.
En C ++, las subexpresiones en expresiones aritméticas no tienen ordenamiento temporal.
a = x + y;
¿Se evalúa x
primero o y
? El compilador puede elegir cualquiera, o puede elegir algo completamente diferente. El orden de evaluación no es lo mismo que la precedencia del operador: la precedencia del operador se define estrictamente, y el orden de evaluación solo se define en función de la granularidad de que su programa tiene puntos de secuencia.
De hecho, en algunas arquitecturas es posible emitir código que evalúa tanto x
como y
al mismo tiempo, por ejemplo, las arquitecturas VLIW.
Hay una diferencia entre una expresión que se evalúa y completar sus efectos secundarios .
La b = a
expresión de asignación se evaluará antes de la resta debido a una mayor precedencia de los paréntesis. Proporcionará el valor de a
como resultado de la evaluación. Sin embargo, la escritura de ese valor en b
puede no completarse hasta el siguiente punto de secuencia, que en este caso es el final de la expresión completa. Por lo tanto, el resultado final de la expresión general no está definido, ya que la resta puede tomar el valor de b
antes o después de la asignación.
Para resolverlo separarlos en dos frases diferentes.
PD: No olvides que los humanos pueden cometer errores al realizar operaciones aritméticas. Por lo tanto, es mejor aclarar las operaciones separándolas en declaraciones diferentes. Espero haberte ayudado.
int main()
{
int a = 3;
int b = 4;
/* Two different Statements*/
b = a;
/* or a = a + b - a */
a = a + b - b;
cout<<"a :"<<a<<" "<<"b :"<<b<<"/n";
return 0;
}
a = b + a - a;
se acaba de escribir como
a = b + a - (b = a)
------ >> (exp 1)
Los siguientes tres resultados son iguales a (exp 1) a = (b + a - (b = a));
a = ((b + a) - (b = a));
a = (b + a) - (b = a);
Observaciones +, - los operadores tienen la misma prioridad y también la asociatividad de izquierda a derecha Por lo tanto, ''b + a'' se ejecuta primero y luego el valor ''a'' se asigna a ''b'' antes de la resta
Ahora observa lo siguiente Cuando a = 10 y b = 20;
a = (b = a) - b + a;
=======> a = 10; b = 10 a = ((b = a) - b + a);
=======> a = 10; b = 10
a = ((b = a) - (b + a));
=======> a = -10; b = 10 De las expresiones anteriores, queda claro que incluso si se ejecuta primero el paréntesis, primero se sigue la asociatividad y luego la precedencia
Nota: Para evitar la confusión entre la precedencia de paréntesis externo e interno, considere la siguiente expresión a = (b + a - (b = a))
=====> Resultado real => a = 20, b = 10; habría sido a = 10, b = 10; (si la precedencia es primaria cuando se compara con la asociatividad) Por lo tanto, mediante el ejemplo anterior podemos decir que la asociatividad es primaria cuando se compara con la precedencia