By gjain

2012-11-09 23:48:09 8 Comments

Following is the test code:

int main()
    int a = 3;
    int b = 4;
    a = a + b - (b = a); 

    cout << "a :" << a << " " << "b :" << b << "\n";    
    return 0;

Compiling this gives the following warning:

> $ 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]

Why can the operation be undefined?

According to my understanding, first the subexpression (b = a) should be evaluated because of higher precedence of (), thus setting b = a. Then, since '+' and '-' have same precedence, the expression would be evaluated left-associatively. Thus, a + b should be evaluated next, and finally the result of (b = a) should be subtracted from a + b. I can't see any sequence-point rule being violated here.


@Ganesh Keerthi D G 2016-09-07 05:11:25

a = b + a - a; is just written as

a = b + a - (b = a)------>> (exp 1)

The following three results same as (exp 1) a = (b + a - (b = a)); a = ((b + a) - (b = a)); a = (b + a) - (b = a);

Observations +, - operators has got same precedence and also left to right associativity Hence 'b+a' gets executed first and then 'a' value gets assigned to 'b' before subtraction

Now observe the following When a = 10 and 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 From the above expressions its clear that even if innermost parenthesis gets executed first the associativity is followed first and then the precedence

Note: To avoid confusion between the precedence of outer and inner parenthesis Consider the following expression a = (b + a - (b = a)) =====> Actual Result => a = 20, b = 10; would have been a = 10, b = 10; (if precedence is primary when compared to associativity) Thus by the above example we can say that associativity is primary when compared to precedence

@M.M 2016-09-07 05:16:25

Sorry but this makes no sense

@dasblinkenlight 2012-11-09 23:50:58

There is a difference between an expression being evaluated and completing its side effects.

The b = a assignment expression will be evaluated ahead of subtraction due to higher precedence of the parentheses. It will provide the value of a as the result of the evaluation. The writing of that value into b, however, may not complete until the next sequence point, which in this case is the end of the full expression. The end result of the overall expression is therefore undefined, because the subtraction may take the value of b before or after the assignment.

@gjain 2012-11-18 01:15:26

Thanks for the crystal clear explanation - "There is a difference between an expression being evaluated and completing its side effects." That hits the Bull's eye.

@fredoverflow 2014-01-27 09:22:55

Your second sentence is wrong. Parenthesis have nothing to do with evaluation order. For example, in the expression f() + (g() + h()), the three functions might get called in any of the 6 possible orders.

@dasblinkenlight 2014-01-27 11:24:18

@FredOverflow By "first" I meant "ahead of subtraction". I corrected the sentence. Thanks!

@Destructor 2015-11-16 05:45:57

@dasblinkenlight: Is behaviour undefined in C++11 & later standard also?

@dasblinkenlight 2015-11-16 11:07:58

@PravasiMeet As far as I know, this remains UB in C++11 and subsequent standards.

@Destructor 2015-11-16 13:13:56

@dasblinkenlight: ok got it.

@Alberto Bonsanto 2012-11-09 23:57:13

To solve it separate them in two different statements.

PS: Don't forget that humans may make mistakes performing arithmetic operations. Therefore is better to make the operations clearer by separating them in different statements. I hope I helped.

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;

@Daniel Kamil Kozar 2014-01-27 07:48:06

-1. While this is an obvious solution to the problem, it does not answer the question at all.

@Fabio says Reinstate Monica 2016-01-04 09:48:22

Actually this is wrong, for 2 reasons. 1) The original expression works (sort of) because it's one expression. If you split it in 2 it doesn't. The very moment you run b = a;, the original value of b is lost forever. If you run this you'll get a :3 b :3. 2) Your second expression a = a + b - b; boils down to a = a;, whereas you want a = b;. You could fix this by using the version in your comment (a = a + b - a;) but it still wouldn't work because of issue number 1. Besides, as indicated by Daniel, this is not what the OP wanted to know.

@Dietrich Epp 2012-11-09 23:50:30

In C++, subexpressions in arithmetic expressions do not have temporal ordering.

a = x + y;

Is x evaluated first, or y? The compiler can choose either, or it can choose something completely different. The order of evaluation is not the same thing as operator precedence: operator precedence is strictly defined, and order of evaluation is only defined to the granularity that your program has sequence points.

In fact, on some architectures it is possible to emit code that evaluates both x and y at the same time -- for example, VLIW architectures.

Related Questions

Sponsored Content

10 Answered Questions

26 Answered Questions

[SOLVED] Why do we need virtual functions in C++?

18 Answered Questions

[SOLVED] Why should C++ programmers minimize use of 'new'?

5 Answered Questions

[SOLVED] Undefined behavior and sequence points

5 Answered Questions

3 Answered Questions

[SOLVED] What is the difference between a sequence point and operator precedence?

5 Answered Questions

[SOLVED] Difference between sequence points and operator precedence? 0_o

  • 2011-09-21 21:11:48
  • Mr.Anubis
  • 415 View
  • 4 Score
  • 5 Answer
  • Tags:   c++

Sponsored Content