Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What will be the result of this condition? Is it defined or compiler-dependant?

If I want to assign a new value to a variable and check if the new value is the same as the old value, I would tend to avoid using temporary variables. Could I do something like this:

if (oldval == (oldval = new_value()))
{
 ... do something
}

?
Would this behaviour be well-defined or is the evaluation priority language or compiler dependant? I could try this and see the result, but it would not guarantee that it will work on other systems as well. I am doing it in C++, so this is the language which interests me the most, but if the behaviour is consistent (or inconsistent) amongst other languages, I would like to know.

Thanks!

like image 531
Matouš Vrba Avatar asked Jun 04 '14 20:06

Matouš Vrba


2 Answers

The order of evaluation of the operand of == is not defined (I am assuming that == is not overloaded). It is not guaranteed whether oldval will evaluate first or oldval = new_value() will. Behavior is undefined in this case.

Avoid writing such expressions that access the value of a variable and also modify that variable elsewhere in the expression.


NOTE: Only the operators, , , &&, || and ?: guarantee that the operand evaluation takes place from left to right. So, there exist sequence point:

  • Between evaluation of the left and right operands of the && (logical AND), || (logical OR) (as part of short-circuit evaluation), and comma operators.
  • Between the evaluation of the first operand of the ternary "question-mark" operator and the second or third operand.
like image 91
haccks Avatar answered Oct 04 '22 22:10

haccks


This would be undefined behaviour because the write to oldval that occurs in oldval = new_value() is unsequenced with respect to a value computation that uses the value of oldval (i.e. the evaluation of the left-hand side of ==).

like image 44
Brian Bi Avatar answered Oct 04 '22 21:10

Brian Bi