Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: fafafa01 en 24 Enero 2017, 10:20 am



Título: Forma de evaluación de los operandos de un operador.
Publicado por: fafafa01 en 24 Enero 2017, 10:20 am
Buenas, leyendo un libro de C, decía que solo en los operandos de los operadores ("&&","||","?:" y ",") se especifica la evaluacion de un operador.

y por lo tanto en el siguiente ejemplo:

Código
  1. a[i]=i++;
  2.  

no se sabe si el subindice es el valor antes o después del incremento.

mi duda es: como el operador [] es el de mas alta precedencia la i  seria el valor viejo cualquier sea el compilador con el que se compile.¿ es acertada la conclusion?

si en cambio, el código seria así:

Código
  1. a[i]=(i++);
  2.  

ahi el subindice si seria el nuevo ya que el operador () esta antes que el []

mi ultima duda:

si un operador unario como cast se pone al lado de una expresión compuesta
Código
  1. (int)(a+b)
  2.  

que se hace primero:
según el operador (), como la asociatividad es de izquierda a derecha, se ara el cast, pero el operador cast se evalúa de derecha a izquierda


Título: Re: Forma de evaluación de los operandos de un operador.
Publicado por: MAFUS en 24 Enero 2017, 15:47 pm
Vale, eso son los puntos de secuencia.

Un punto de secuencia marca cuándo una instrucción se ha completado y no va a haber efectos secundarios en posteriores procesos.

Como has dicho el operador de asignación ( = ) no marca un punto de secuencia por lo que el compilador puede elegir arbitrariamente que parte del igual quiere resolver primero. Si es la parte izquierda no pasará nada, se dereferenciará la dirección de la variable a[i] y después pasará a la parte derecha para calcular el valor que debe asignar, por lo que el postincremento no afectará. Pero si primero decide evaluar la parte derecha para saber qué valor debe asignar, al evaluar la parte izquierda i habrá aumentado por el postincremento.

Si buscas más información sobre efectos secundarios y puntos de secuencia (sequence points) verás que la historia es bastante complicada. Basta con que te quedes que no hay que mezclar según que expresiones en una instrucción.


Título: Re: Forma de evaluación de los operandos de un operador.
Publicado por: ivancea96 en 24 Enero 2017, 17:41 pm
http://en.cppreference.com/w/cpp/language/operator_precedence (http://en.cppreference.com/w/cpp/language/operator_precedence)

Esos casos no dan mucho pié a error. Un post-incremento no se ejecuta hasta el final de la instrucción/línea (de forma genérica).

Ese (i++) que pusiste, no es el operator(). "i()" es el operator (), que es como una llamada a función. Rodear unas operaciones con () no es un operador. Simplemente haces que ese bloque se ejecute completo (cuando se necesite) antes de continuar evaluando.

Para probar estas cosas de forma práctica, siempre puedes crear una clase para ello:

Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class Test{
  6. public:
  7. Test operator+(const Test& test){
  8. cout << " +";
  9. }
  10.  
  11. Test operator++(){
  12. cout << " ++_";
  13. }
  14.  
  15. Test operator++(int){
  16. cout << " _++";
  17. }
  18.  
  19. Test operator[](const Test& test){
  20. cout << " []";
  21. }
  22.  
  23. Test operator=(const Test& test){
  24. cout << " =";
  25. }
  26.  
  27. operator int(){
  28. cout << " int";
  29. }
  30. };
  31.  
  32. int main(){
  33. cout << "Order:";
  34.  
  35. Test a,b;
  36.  
  37. a[++a] = b++;
  38. cout << endl;
  39.  
  40. (int)(a+b);
  41. cout << endl;
  42.  
  43. (int)a+b;
  44. cout << endl;
  45. }