1

I have a doubt about this code:

int i, x, z = 4, y = 1;
i = x = z += y++;

Which is the value of i? Can we know that value or not?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Jatos
  • 333
  • 2
  • 13
  • @πάνταῥεῖ I think there is one in the initialization of z because we don't know the y value when z is initialized – Jatos Aug 03 '19 at 11:29
  • *"don't know the y value"* Why not? It's `1`. – HolyBlackCat Aug 03 '19 at 11:29
  • 1
    The value is `5` isn't it? I don't see the problem. – john Aug 03 '19 at 11:30
  • But it is y++ and I think that it is not known if it is incremented before or after the initialization of z – Jatos Aug 03 '19 at 11:31
  • *we don't know the y value when z is initialized* even if that were true (I'm not sure) why would it be a problem? We know the value of `y` when it is first used. – john Aug 03 '19 at 11:31
  • `y` is incremented after `z` has been initialised. It's incremented in the following statement. I'm really not sure where your doubts are coming from. – john Aug 03 '19 at 11:32
  • I found this code in a book of c++. It says that i could also be 6 – Jatos Aug 03 '19 at 11:33
  • @Jatos How does the book explain that `i` might be `6`? – john Aug 03 '19 at 11:35
  • 3
    This is not good code. Forget about it and move on. – Lightness Races in Orbit Aug 03 '19 at 11:36
  • *"if it is incremented before or after the initialization of z"* Note that `z` is initialized here: `z = 4`. The next line *assigns* to `z`. – HolyBlackCat Aug 03 '19 at 11:36
  • Okay thank you. I was confused by the book in fact – Jatos Aug 03 '19 at 11:37
  • That **assignment** to `i` is not an **initialization**. `i` gets default initialized in the first line, resulting in an indeterminate value. It gets assigned a value in the second line, and that value is determined by the rest of the code in that line. Both `z` and `y` are initialized in the first line, and their initial values are used in the second line to determine the new values of all four variables. – Pete Becker Aug 03 '19 at 12:59
  • @LightnessRacesinOrbit That's not good advice, for two reasons: 1. How does history repeat itself? 2. it does not help them understand it. The fact that they do not understand how this works indicates that they don't have the best understanding of C++ syntax. There's nothing wrong with learning that. Everyone should know about it before writing any serious code. –  Aug 03 '19 at 13:25
  • @Sahsahae "Forget about it and move on" then come back to it later perhaps – Lightness Races in Orbit Aug 03 '19 at 17:13

3 Answers3

3

First of all, have you tested if this compiles at all?

If not, then why?

Unless you write some code that invokes UB, compiler, regarding basic syntax of the language, has most of the answers you'll ever need. Please test it yourself, and if it's still not clear, or behaves weirdly, then it's something worth asking.

In this case, it's valid, so let's go through it.

#include <iostream>

int main() {
    int i, x, z = 4, y = 1;
    i = x = z += y++;

    std::cout << "i=" << i << std::endl;
}

I compiled, ran it, and here's the result:

$ g++ test.cpp -o test
$ ./test
i=5

So, what is actually going on in this line?

i = x = z += y++;

First of all, it's easier to understand when you add parentheses so it's perfectly obvious what is evaluated and when:

i = (x = (z += (y++)));
  1. i is a result of assignment to x;
  2. x is a result of addition assignment to z;
  3. z is a result of z + (y post increment);

You can then work your way backwards through the list, and will arrive at the correct result:

  1. y++ evaluates to simply y, because post increment affects only value of y, not the result of expression itself;
  2. z is then z + y, which is 4 + 1, or 5;
  3. intermediate expression becomes i = x = z; (or, form that's too obvious, i = (x = z);), and that means that i, just like x is 5.

Whatever you do, please don't actually write code like this, while it's easy to deconstruct, it's not something that is easy to understand at a first glance, and that, more often than not, causes confusion.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • The questioner could be uncertain about whether to trust the compiler (s)he has today and whether it will exhibit all possible behaviours of the program. Apart from the fact that UB (undefined behaviour) could have been invoked, there could be unspecified behaviour, or implementation defined behaviour, and the questioner might not know whether the behaviour they get from their compiler is one of those. – codeshot Aug 03 '19 at 11:57
  • 3
    Re “Unless you write some code that invokes UB, compiler has all the answers you'll ever need.”: This is incorrect. A compiler may have behavior that is implementation-defined but not undefined, and there are additional categories of behavior that are neither fully specified by the C standard nor undefined. – Eric Postpischil Aug 03 '19 at 12:06
  • I've edited my answer to not misinform people on that one. I am well aware that there's cases where compiler will do whatever it wants without telling you that you're doing it wrong. Thank you. –  Aug 03 '19 at 13:09
2

Can we know that value or not?

Yes.

Which is the value of i?

5

since you add y to i, where their values are 4 (since i gets assigned the value of z, which is 4) and 1 respectively.

y is incremented after z has been initialized. It's incremented in the following statement, as @john commented.


As @LightnessInOrbit commented, this is not good code. Forget about it and move on.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • To be precise I believe it's not actually certain **when** the increment is performed. All that is sure is that the value of `i` used is the value prior to the increment. – john Aug 03 '19 at 11:36
  • I focused on the bottom part of my answer, I think your initial comment @john described it best, so instead of paraphrasing it, I just injected it into my post, is that OK? – gsamaras Aug 03 '19 at 11:42
  • Is the postfix increment of y really done after the value is assigned to i, or is the value of (y++) determined before the postfix increment so the increment doesn't affect the assignment regardless of when it's performed? – codeshot Aug 03 '19 at 11:56
  • @codeshot aww that were leftovers from my last edit, discarded them, thanks! – gsamaras Aug 03 '19 at 11:59
0

Yes the value of i is 5.

Just trace the code.

y++ post increement i,e first assign the value then increement so Y= 4. Next

z += y shorthand operation i,e.., z= z + y ,initially z=4 so 5 = 4+ 1 so Z=5

x = z i.e, x = 5 Next

i = x i.e, i = 5.