0

I have been trying to learn the associativity of operators in C++ and I have come across a code segment :

int a = 10;
int C = a++ + ++a + ++a +a;

I have also studied that ++a is right to left associative and a++ is left to right associative. Also + is left to right associative. But I don't understand how to apply this knowledge in this problem.

I am confused that how this statement will be parsed by my compiler?

I am also puzzled that since putting spaces don't matter much why does removing spaces like :

int C = a+++++a+++a+a;  //error: lvalue required as increment operand

generate an error? Please help me understand this concept.

Thanks!

utkarsh867
  • 87
  • 1
  • 10
  • 1
    First operator precedence: http://en.cppreference.com/w/cpp/language/operator_precedence, second spaces do matter - especially if they can be ambiguous. Compiler parsers can do many things, but in general: if a human can't read it - neither can a compiler ;-) – Jason De Arte Mar 23 '16 at 06:15
  • 1
    This doesn't have anything to do directly with parsing, but this statement is undefined. According to the standard, §1.9.15, p.11 says: "Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.", and further: "If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined." – smiling_nameless Mar 23 '16 at 06:23
  • I guess I should also say: if you're trying to figure out what the value of C will be, give up; you can't. – smiling_nameless Mar 23 '16 at 06:26
  • 1
    Thanks a lot @MaxBozzi I am a beginner in C++ programming and the statement that you have written is making very little sense to me but it seems to me that it is something that I should learn. Can you please simplify it a bit? – utkarsh867 Mar 23 '16 at 06:28
  • @MaxBozzi My book says that the answer should be 48. I am trying to figure out how. – utkarsh867 Mar 23 '16 at 06:29
  • 2
    @utkarsh867 Okay --- your book is making assumptions about the way a particular compiler works. According to the standard, the result can be _anything at all_. The expression has no defined value; different compilers can spit out different things or do anything they want. – smiling_nameless Mar 23 '16 at 06:31
  • 2
    @utkarsh867 If you don't understand the phrasing from the standard, that's okay. It's remarkably hard to read (it's designed for the engineers who implement C++!), but it's the law. To paraphrase, you can't modify a value at the same time you do a computation with it; those computations happen in any order. Because of this, your textbook is *wrong*; it _cannot_ give `48` (or any number) as the definitive result of that expression, different implementations can give different, arbitrary values as the result. I still can't actually answer your question about the parser, though! :) – smiling_nameless Mar 23 '16 at 06:41
  • Ok. Thanks a lot @MaxBozzi :) – utkarsh867 Mar 23 '16 at 06:46
  • For the parsing, look up [**maximal munch**](https://en.wikipedia.org/wiki/Maximal_munch). I recently saw a duplicate to this question, but can't find it right now unfortunately. – juanchopanza Mar 23 '16 at 07:03

2 Answers2

2

First of all space does matter- It helps compiler to resolve ambiguity.

Whenever there is an expression, compiler parse it from right to left. It looks for all the post increment operators first and then pre increment operators as later has lower precedence than the former. So any modification done by pre-increment operator will be applied to the whole expression and then changes of post-increment will be applied in the next expression.

Explanation

  • ++a first increments the value of a and then returns lvalue referring to a, so if a is used then it will be the incremented value.

In your case there are total two ++a, thus the value of a will be incremented to 12 and thus assigned to a. so all the a in your expression will be holding the value 12 giving you the value of c=48.

  • a++ first returns an rvalue whose value is a, that is the old value, and then increments a at an unspecified time before the next full expression.

In your case if you use value of a after the expression it will be 13 as in the previous expression there was only one a++.

For eg.

int a = 10;
int C = a++ + ++a + ++a +a; // Here a=12 and the post increment effect will be applied in the next expression
int B = a + a; // Here a=13 the effect of previous post increment.

Regarding Error

With no space in expression, compiler will get confused when it will parse expression and thus dosent have any value to do the assignment.

PS: lvalue is a value that can be the target of an assignment. In C/C++ the pre-increment (decrement) and the post-increment (decrement) operators require an L-value expression as operand. Providing an R-value or a const qualified variable results in compilation error.

secretgenes
  • 1,291
  • 1
  • 19
  • 39
2

Putting aside the fact that it would result in UB (as no sequence points between these multiple increments of the same variable)

a+++++a+++a+a

is parsed (as parser is greedy) as

((a++)++) + (a++) + a + a

and (a++)++ is illegal when a is a built-in type as int.

Jarod42
  • 203,559
  • 14
  • 181
  • 302