Why does enclosing increment operator in parentheses not make a difference?
Asked Answered
P

5

5

Why is that the same and where is documentation backing this up?

My teacher insists "z = (y++)" should do y++ first and then attribute the result to z.

So like this:

int z, y = 10;
z = (y++);
printf("%d", z); //z = 10 or 11? and why?

Thank you.

Pinnatifid answered 27/10, 2016 at 10:28 Comment(11)
The post-increment operator increments the value after the expression is evaluated. Parentheses don't change that.Cyrilla
@2501 - The close reason doesn't matter too much since the question is still unclear and should be closed as suchImpregnable
@Sayse, I think the question "Why is that the same and where is documentation backing this up?" is perfectly clear.Alaynaalayne
@Impregnable That is not an argument to close it for invalid reasons.Scandalize
@Pinnatifid better email this question link to your teacher.Amersham
@GiorgiMoniava Thank you.Scandalize
I think your teacher is confused between y++ and ++y, which would give different values to zAhlers
@Ahlers but the parentheses still make no difference.Amersham
It rather seems like the teacher expects a parenthesis to have a built-in sequence point, which isn't true. As if it would behave just as this obscure example: z = (y++,y); You could ask your teacher "what is a sequence point" and if they can't answer, they probably shouldn't be teaching C.Yclept
@WeatherVane Correct.Ahlers
y++ has to be evaluated before its result can be assigned to z, regardless of the parentheses. Your teacher is simply confused over what the result of y++ should be.Madaih
A
9

Your teacher is wrong. In C, the statements z = (y++); and z = y++; must be equivalent.

According to section 6.5.2.4 of N1570 (the standard draft of C11):

The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). [...] The value computation of the result is sequenced before the side effect of updating the stored value of the operand.

Both the postfix ++ operator and parenthesis have the same value: they just pass the value of their operand. So y, y++, (y), (y++), and (y)++ all have the same value: the value of y at the time that the expression is evaluted.

The only thing that postfix ++ does differently, is that it has a side-effect sometime after the calculation of its operand (the expression immediately before it). In the case of z = (y++); printf("%d", z);, the side-effect of postfix ++ will occur

  • after the value of the expression y is "calculated" (which really is just reading the variable in this case), and
  • before the printf("%d", z); statement, because compound statements (any list of statements between curly brackets) have sequencing semantics.

Beyond that, you have no control when exactly y is modified. This is also why a statement like z = y++ = y++ has undefined behaviour: the side-effect of the first y++ may occur before or during or after the side-effect of the second y++.

Attraction answered 27/10, 2016 at 11:12 Comment(2)
I actually don't see where the teacher is wrong. The way the question is phrased the teacher is perfectly right. The result of (y++) is assigned to z. It's a truism. That's what assignment is.Miculek
The way I read it, the teacher would say that int y = 10, z; z = (y++); would result in z == 11, as it "should do y++ first" (where "do" includes the side-effect). But something may have been lost in translation; we can only take OP's word for it that this is what the teacher said. Then again, I've had TAs tell me that you can't implement memcpy by looping *dst++ = *src++;, because that would just change the data in the buffers. It's not unheard of that instructors don't understand C.Attraction
Y
3

Yes it is the same. This is guaranteed by the operator precedence rules in standard C, ISO 9899:2011 6.5/3. A parenthesis is a primary expression with the highest precedence possible (6.5.1), higher than the postfix ++ operator (6.5.2), which in turn has higher precedence than the = operator (6.5.16).

Meaning that all of these are 100% equivalent:

z = y++;
(z) = y++;
z = (y++);
(z) = (y++);
(z = y++);

All of these cases will evaluate y, assign that value to z, then increment y by 1.

(Postfix ++ behavior is defined as: "The value computation of the result is sequenced before the side effect of updating the stored value of the operand.")

Note however that it is considered bad practice to mix the ++ operator with other operators, since it has the built-in side effect of updating the value. This can easily create bugs, for example y=y++; would have been a severe bug. In addition, multiple operators on a single line is often hard to read.

The canonical way to write that expression is therefore:

z = y;
y++;
Yclept answered 27/10, 2016 at 10:55 Comment(0)
S
1

The advantage of Parenthesis comes into picture only when you have more operators in a expression i.e in a pool of operations the operation in Parenthesis is carried out first

int z, y = 10;
z = (y++);
printf("%d", z);

Coming to this in your program the parenthesis has nothing to do with the increment operator. The increments happens after assignment (since post increment) hence the output is 10

Serinaserine answered 27/10, 2016 at 10:37 Comment(1)
@George the expression given by you produces a serious error !!Serinaserine
H
1
  1. First Learn about pre increment and post increment.
  2. Action of post increment will remain same doesn't matter if you apply braces. Parentheses is just a facility that gives direction to the compiler but can't compell it. There are multiple such scenerios where braces won't have any effect. for example

printf("%d %d",fun1(),(fun2())) here even if fun2 is in braces, it's not guranteed that it would be invoked first.

Again, it's just a request to compiler. Compiler may or may not accept this request depending on other rules.

Hygroscopic answered 27/10, 2016 at 10:45 Comment(4)
printf("%d %d",fun1(),(fun2())) here fun2 is invoked first read about the printf argumentsSerinaserine
@Serinaserine No, it is unspecified which is called first.Scandalize
@Scandalize can you provide a link to that so that i can understandSerinaserine
@Serinaserine #2421185Scandalize
M
0

My teacher insists "z = (y++)" should do y++ first and then attribute the result to z.

I would say that as written here "the teacher" is right, but someone misunderstands why. y++ is done first, then its result is assigned to z. It's the same thing as saying that in a=(b+c). b+c is done first, then the result of that expression is assigned to a. It's a truism, that's what assignment is. (let's not mix sequence points into this since sequence points are not involved in this particular question)

Where I think someones confusion comes in is what y++ means. It's an expression with a value and a side effect. The value of the expression doesn't change regardless of parentheses just like it wouldn't change with b+c. In z = EXPRESSION; is going to be assigned the value of the expression regardless of how many parentheses you put around it.

Think of it like a function. z = y++; can be seen as z = function();. What the function does internally doesn't matter for what gets assigned to z, only the return value matters. That's what expressions can be seen as.

Miculek answered 27/10, 2016 at 13:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.