He ejecutado el siguiente código en Code::Blocks 10.05 en Windows 7.
int a=0,b=0,c; c=a++&&b++; printf("\na=%d\nb=%d\nc=%d\n\n",a,b,c);La salida que obtuve se da a continuación,
a=1 b=0 c=0Esto tiene mucho sentido debido a la evaluación de cortocircuito.
La expresión a++ es un incremento posterior y 0 se devuelve a la lógica y ( && ). Por lo tanto, la parte b++ no se evalúa ya que tanto 0 && 0 como 0 && 1 se evalúan como 0 .
Pero aquí surge mi duda. El valor de precedencia de los operadores establece claramente que ++ tiene mayor precedencia que && . Entonces, mi entendimiento fue así, tanto a++ como b ++ se evalúan y luego && solo verifica el resultado de la expresión a++ para tomar una decisión. Pero esto no ha sucedido, aquí solo se evalúa a++ .
¿Cuál es la razón de este comportamiento? ¿ && ser un punto de secuencia tiene algo que ver con este comportamiento? Si es así, ¿por qué decimos que && tiene una precedencia menor que ++ ?
Está confundido acerca de la precedencia y el orden de evaluación .
La precedencia define cómo se agrupan los operadores, es decir
c = a++ && b++;es equivalente a:
c = ((a++) && (b++)); El orden de evaluación define cómo se evalúa la expresión, el cortocircuito de && significa que a++ se evalúa primero, si es cero, al final; si no es cero, entonces se evalúa b++ .
Como otro ejemplo:
c = (a++) + (b++); ¿Se evalúa a++ antes que b++ ? La respuesta es que no lo sabemos. La mayoría de los operadores no definen el orden de evaluación. && es uno de los pocos operadores que definen. (El resto son || , , y ?: )
Aquí hay dos conceptos: orden de precedencia y orden de evaluación. El orden de precedencia tendrá un impacto solo si se evalúa una expresión (o subexpresión).
En general, el orden de evaluación no está secuenciado. Dado un operador, sus operandos pueden evaluarse en cualquier orden. Los argumentos de una función se pueden evaluar en cualquier orden.
Del estándar C++:
1.9 Ejecución del programa
15 Excepto donde se indique, las evaluaciones de operandos de operadores individuales y de subexpresiones de expresiones individuales no están secuenciadas.
y
8.3.6 Argumentos predeterminados
9 Los argumentos predeterminados se evalúan cada vez que se llama a la función. El orden de evaluación de los argumentos de función no está especificado.
Para el operador lógico AND, && , el estándar C++11 dice:
5.14 Operador lógico AND
1 El operador
&&agrupa de izquierda a derecha. Ambos operandos se convierten contextualmente al tipobool(Cláusula 4). El resultado estruesi ambos operandos sontrueyfalseen caso contrario. A diferencia&,&&garantiza una evaluación de izquierda a derecha: el segundo operando no se evalúa si el primer operando esfalse.
Se especifica una excepción similar para el operador lógico OR, || .
Dado que b++ no se evalúa debido a un cortocircuito de la expresión debido al operador && , el orden de precedencia de los operadores no tiene importancia en este caso particular.