c++ - ¿Orden de evaluación de argumento "IF"?
if-statement order-of-evaluation (6)
Cada cómputo de valor y efecto secundario del primer argumento (izquierdo) del operador AND lógico incorporado && y el operador O lógico incorporado || se secuencia antes de cada cálculo de valor y efecto secundario del segundo argumento (derecho).
Lea aquí para obtener una explicación más exhaustiva del conjunto de reglas: evaluación de orden
if(a && b)
{
do something;
}
¿hay alguna posibilidad de evaluar los argumentos de derecha a izquierda (b -> a)?
si es "sí", ¿qué influye en la orden de evaluación?
(Estoy usando VS2008)
Con C ++ solo hay unos pocos operadores que garantizan la orden de evaluación
operator &&
evalúa el operando izquierdo primero y si el valor es lógicamentefalse
entonces evita evaluar el operando correcto. El uso típico es, por ejemplo,if (x > 0 && k/x < limit) ...
que evita la división por cero problemas.operator ||
evalúa el operando izquierdo primero y si el valor es lógicamentetrue
entonces evita evaluar el operando correcto. Por ejemplo,if (overwrite_files || confirm("File existing, overwrite?")) ...
no pedirá confirmación cuando se establezca el flagoverwrite_files
.operator ,
evalúa el operando izquierdo primero y luego el operando derecho de todos modos, devolviendo el valor del operando derecho. Este operador no se usa con mucha frecuencia. Tenga en cuenta que las comas entre parámetros en una llamada a función no son operadores de coma y el orden de evaluación no está garantizado.El operador ternario
x?y:z
evalúax
primero, y luego, dependiendo del valor lógico del resultado, evalúa soloy
o soloz
.
Para todos los demás operadores, el orden de evaluación no está especificado.
La situación es realmente peor porque no es que el orden no esté especificado, sino que ni siquiera hay un "orden" para la expresión, y por ejemplo en
std::cout << f() << g() << x(k(), h());
es posible que las funciones se hgkxf
en el orden hgkxf
(esto es un poco perturbador porque el modelo mental de <<
operador transmite de alguna manera la idea de secuencialidad pero en realidad respeta la secuencia solo en el orden en que los resultados se transmiten y no en el orden en que se calculan los resultados).
Obviamente, las dependencias de valor en la expresión pueden introducir cierta garantía de orden; por ejemplo, en la expresión anterior, se garantiza que se k()
tanto k()
como h()
antes de x(...)
porque los valores de retorno de ambos son necesarios para llamar a x
.
Tenga en cuenta también que las garantías para &&
, ||
y ,
son válidos solo para operadores predefinidos. Si sobrecarga esos operadores para sus tipos, serán en ese caso similares a las llamadas a funciones normales y el orden de evaluación de los operandos no se especificará.
El operador &&
integrado siempre evalúa primero su operando izquierdo. Por ejemplo:
if (a && b)
{
//block of code
}
Si a
es false
, entonces b
no se evaluará.
Si quieres que b
sea evaluado primero, y a
solo si b
es verdadero, simplemente escribe la expresión al revés:
if (b && a)
{
//block of code
}
En este caso, ya que está usando &&
, a
siempre se evaluará primero porque el resultado se usa para determinar si se debe o no cortocircuitar la expresión.
Si a
devuelve falso, entonces b
no puede evaluar en absoluto.
Evaluará de izquierda a derecha y pondrá en cortocircuito la evaluación si puede (por ejemplo, si se evalúa como falso, no se evaluará b).
Si te importa el orden en el que se evalúan, solo tienes que especificarlos en el orden de evaluación deseado en tu declaración if.
La orden de evaluación está especificada por el estándar y es de left-to-right
. La expresión más a la izquierda siempre se evaluará primero con la cláusula &&
.
Si quieres que b
sea evaluado primero:
if(b && a)
{
//do something
}
Si ambos argumentos son métodos y desea que ambos se evalúen independientemente de su resultado:
bool rb = b();
bool ra = a();
if ( ra && rb )
{
//do something
}