-8
#include <iostream.h>
int main()
{
  int a = 2;
  int b = 3;
  a++ += b;
  std::cout << a;
}

My understanding of this had been that this expression would first evaluate a+b, store that value in a and then increment it. What is happening here?

YSC
  • 38,212
  • 9
  • 96
  • 149
shinama99
  • 51
  • 6
  • 2
    What error? what `a`? what `b`? – Matthieu Brucher Jan 29 '19 at 13:42
  • 2
    Please post a [mcve](https://stackoverflow.com/help/mcve)... – user1810087 Jan 29 '19 at 13:42
  • 2
    depending on what type `a` and `b` are this expression can literally do anything. The answer assumes they are built in number types, but you should really include a [mcve] – 463035818_is_not_an_ai Jan 29 '19 at 13:45
  • 1
    If you want to do what you wrote in your question, then you should probably write it as `a+=b; a++;` instead of mangling it together into an error-prone construct. – Blaze Jan 29 '19 at 13:46
  • 4
    Compile fine [here](http://coliru.stacked-crooked.com/a/88b94084bcc56222) :-) – Jarod42 Jan 29 '19 at 13:47
  • error: lvalue required as left operand of assignment... a++ itself an operation, the left side (lvalue) required a variable where processed data can be stored. – Vineet Jan 29 '19 at 13:49
  • 3
    This is **not** a duplicate of any undefined behaviour. This code is not allowed to compile in standard C++. Reopened. – Bathsheba Jan 29 '19 at 13:55
  • Possible duplicate of [Undefined behavior and sequence points](https://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) – Richard Jan 29 '19 at 14:09
  • If you mean `a = a + b + 1`; why not write it? – Tim Randall Jan 29 '19 at 14:27
  • So much wrong with that code snippet. `` should be ``, `main_program` should be `int main()`, `const int a` means you cannot do `a++`, `cout` should be `std::cout` or have a prior `using std::cout`. – Eljay Jan 29 '19 at 15:33
  • @TimRandall You changed the semantics of the program by swapping `a` and `b`. `a` is even a const and should not be incrementable at all now. Rather than swapping a and b fix the entrypoint `main_program` -> `int main()` I reverted your change –  Jan 30 '19 at 09:54
  • @Eljay see above comment about const a –  Jan 30 '19 at 10:02

3 Answers3

9

This is an error1:

a++ += b

because a++ returns a temporary (a pr-value) the language forbids you to modify since it is discarded as soon as the full expression has been evaluated. This is a kind of fail safe.


My understanding of this had been that this expression would first evaluate a+b, store that value in a and then increment it.

No it doesn't. According to operator precedences, ++ evaluates before +=.


1) This answer assumes a and b are builtin types or well-behaved user-defined class types.

YSC
  • 38,212
  • 9
  • 96
  • 149
  • This is kind of true. For built in types this is correct. For user types it doesn't have to be. – NathanOliver Jan 29 '19 at 13:44
  • @NathanOliver Sometimes I prefer a simple half-truth to a complex full one. – YSC Jan 29 '19 at 13:45
  • 2
    Given the minimal information provided by OP, I think it's fair to assume that `a` and `b` are `int` or something similar. – Blaze Jan 29 '19 at 13:47
0

For build in types this is a compile-time-error, as asignment needs an lvalue and a++ (which is due to operator precedence evaluated first) is an rvalue. In your example the compiler will issue an error like this see compiler-explorer:

<source>: In function 'int main()':

<source>:6:9: error: lvalue required as left operand of assignment

6 |  a++ += b;

  |         ^

Compiler returned: 1

If you have a custom type (in this case nonsense, but for demonstration) which looks like this

class A
{
    public:

    A operator++(int)
    {
        return A{};
    }

    A operator+=(const A&)
    {
        return A{};
    }

    int i;
};

int main()
{
    A a;
    A b;
    a++ += b;

    return 0;
}

It compiles without problems as a++ now yields a lvalue.

YSC
  • 38,212
  • 9
  • 96
  • 149
0

Aside from wrong entry point and header there are two problems with this code.

a is defined as const so it cannot be a lvalue, so cannot be affected by ++ or += operator.Or any assignment. It's a constant!

Increment operator++ doesn't return a lvalue as well so its result cannot be an argument of assignment operators.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • In the OPs question it originally read b++ ... So you should not point that out –  Jan 30 '19 at 09:57
  • There's been some bad editing on the Q. I've fixed it along with Pi's answer so everything matches the question's title. – YSC Jan 30 '19 at 19:03