Difference between i++ and (i)++ in C
Asked Answered
M

2

51
int i = 3;
int j = (i)++;

vs

int i = 3;
int j = i ++;

Is there a difference between how the above two cases are evaluated?

Is the first case equivalent to incrementing an rvalue or is it undefined behaviour?

Monoxide answered 27/2, 2019 at 15:5 Comment(4)
Seemingly arbitrary usage of parentheses is common in macro definitions. Where they do make a big difference, you'd like the error message you get. Well, usually.Mantua
There is no difference in those for ints. However, it is not always the case and you must be cautious when combining brackets and operators, @govin-parmar have shown a good example what can happen with pointers.Pachston
To be clear, both of these cases are well-defined (i.e., not UB) and will store 3 in j.Muumuu
"am I overthinking it" yes.Ionia
F
97

i++ and (i)++ behave identically. C 2018 6.5.1 5 says:

A parenthesized expression is a primary expression. Its type and value are identical to those of the unparenthesized expression. It is an lvalue, a function designator, or a void expression if the unparenthesized expression is, respectively, an lvalue, a function designator, or a void expression.

The wording is the same in C 1999.

Fredric answered 27/2, 2019 at 15:8 Comment(2)
For completeness, has this always been the case? I mean, I know it has, but your reference says C 2018 (i.e. the latest version), so it can't hurt to have it spelled out.Bothnia
@MrLister Yes, even pre-ANSI C (1978) had this behavior. It's not spelled out formally (so little was), but it's required for some examples in the first edition of K&R, such as (*ptr)++.Zolly
D
56

In your simple example of i++ versus (i)++, there is no difference, as noted in Eric Postpischil's answer.

However, this difference is actually meaningful if you are dereferencing a pointer variable with the * operator and using the increment operator; there is a difference between *p++ and (*p)++.

The former statement dereferences the pointer and then increments the pointer itself; the latter statement dereferences the pointer then increments the dereferenced value.

Demarcate answered 27/2, 2019 at 15:19 Comment(11)
So for example, if you define a macro #define postinc(x) x++ then postinc(*p) will not do what you expect given the function-like notation. That's why in writing macros it's common to heavily parenthesize e.g. #define postinc(x) ((x)++)Daub
Your answer boils down to "parenthesis can be used to enforce operator precedence" which is obvious and not what the OP asked.Minus
@GiacomoAlzetta There was a lengthy discussion on this answer that was removed by moderation. The short of it is that I felt that explaining this particular nuance is important because mixing these two expressions up in particular is a common source of bugs for beginners in C.Demarcate
@GiacomoAlzetta Remember, SO answers are supposed to be useful for anyone reading the question, not just the OP or people already familiar with the technology being asked about. In my experience the most common usage of (expr)++ is to increment a dereferenced value, so giving beginners the impression that expr++ is equivalent is detrimental.Demarcate
I.e. *p++ is equivalent to *(p++)?Analyse
@SolomonUcko No, the first would dereference the pointer and then increment it. The second would increment the pointer THEN dereference it.Sharper
@Sharper So it is impossible to add parentheses within *p++ without changing the meaning?Analyse
@SolomonUcko Sure, (*p++);Demarcate
@GovindParmar That wouldn't be within it; it would be around it. Also, where would this be covered in the specifications?Analyse
@Sharper Actually, when would the order of those operations matter in C? Post-increment returns the original value. Supporting references: https://mcmap.net/q/354524/-does-p-increment-after-dereferencing-duplicate, denniskubes.com/2012/08/14/do-you-know-what-p-does-in-c, en.cppreference.com/w/c/language/operator_precedence, https://www.quora.com/What-is-the-difference-between-*p++-and-++*p-in-pointers-of-c++/answer/Gajanan-HegdeAnalyse
The statement is correct but does not answer the question. There are more pitfalls with ++.Ionia

© 2022 - 2024 — McMap. All rights reserved.