Difference between i++ and (i)++ in C

Clash Royale CLAN TAG#URR8PPP
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?
c language-lawyer increment evaluation
add a comment |
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?
c language-lawyer increment evaluation
18
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.
– Hans Passant
Feb 27 at 16:38
3
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.
– Tomasz Kornuta
Feb 28 at 3:20
1
To be clear, both of these cases are well-defined (i.e., not UB) and will store 3 inj.
– osuka_
Feb 28 at 15:09
1
"am I overthinking it" yes.
– alk
Mar 5 at 20:10
add a comment |
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?
c language-lawyer increment evaluation
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?
c language-lawyer increment evaluation
c language-lawyer increment evaluation
edited Mar 10 at 9:24
Max Shvartsman
92
92
asked Feb 27 at 15:05
Polaris000Polaris000
501820
501820
18
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.
– Hans Passant
Feb 27 at 16:38
3
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.
– Tomasz Kornuta
Feb 28 at 3:20
1
To be clear, both of these cases are well-defined (i.e., not UB) and will store 3 inj.
– osuka_
Feb 28 at 15:09
1
"am I overthinking it" yes.
– alk
Mar 5 at 20:10
add a comment |
18
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.
– Hans Passant
Feb 27 at 16:38
3
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.
– Tomasz Kornuta
Feb 28 at 3:20
1
To be clear, both of these cases are well-defined (i.e., not UB) and will store 3 inj.
– osuka_
Feb 28 at 15:09
1
"am I overthinking it" yes.
– alk
Mar 5 at 20:10
18
18
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.
– Hans Passant
Feb 27 at 16:38
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.
– Hans Passant
Feb 27 at 16:38
3
3
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.
– Tomasz Kornuta
Feb 28 at 3:20
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.
– Tomasz Kornuta
Feb 28 at 3:20
1
1
To be clear, both of these cases are well-defined (i.e., not UB) and will store 3 in
j.– osuka_
Feb 28 at 15:09
To be clear, both of these cases are well-defined (i.e., not UB) and will store 3 in
j.– osuka_
Feb 28 at 15:09
1
1
"am I overthinking it" yes.
– alk
Mar 5 at 20:10
"am I overthinking it" yes.
– alk
Mar 5 at 20:10
add a comment |
2 Answers
2
active
oldest
votes
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.
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.
– Mr Lister
Feb 28 at 7:17
7
@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)++.
– Sneftel
Feb 28 at 9:10
add a comment |
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.
7
So for example, if you define a macro#define postinc(x) x++thenpostinc(*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)++)
– Daniel Schepler
Feb 28 at 1:12
10
Your answer boils down to "parenthesis can be used to enforce operator precedence" which is obvious and not what the OP asked.
– Giacomo Alzetta
Feb 28 at 9:53
3
@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.
– Govind Parmar
Feb 28 at 12:05
7
@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 thatexpr++is equivalent is detrimental.
– Govind Parmar
Feb 28 at 12:12
3
@SolomonUcko No, the first would dereference the pointer and then increment it. The second would increment the pointer THEN dereference it.
– ale10ander
Feb 28 at 20:21
|
show 6 more comments
protected by P.W Mar 1 at 5:10
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
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.
– Mr Lister
Feb 28 at 7:17
7
@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)++.
– Sneftel
Feb 28 at 9:10
add a comment |
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.
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.
– Mr Lister
Feb 28 at 7:17
7
@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)++.
– Sneftel
Feb 28 at 9:10
add a comment |
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.
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.
edited Feb 28 at 7:31
answered Feb 27 at 15:08
Eric PostpischilEric Postpischil
79.2k886167
79.2k886167
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.
– Mr Lister
Feb 28 at 7:17
7
@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)++.
– Sneftel
Feb 28 at 9:10
add a 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.
– Mr Lister
Feb 28 at 7:17
7
@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)++.
– Sneftel
Feb 28 at 9:10
2
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.
– Mr Lister
Feb 28 at 7:17
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.
– Mr Lister
Feb 28 at 7:17
7
7
@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)++.– Sneftel
Feb 28 at 9:10
@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)++.– Sneftel
Feb 28 at 9:10
add a comment |
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.
7
So for example, if you define a macro#define postinc(x) x++thenpostinc(*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)++)
– Daniel Schepler
Feb 28 at 1:12
10
Your answer boils down to "parenthesis can be used to enforce operator precedence" which is obvious and not what the OP asked.
– Giacomo Alzetta
Feb 28 at 9:53
3
@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.
– Govind Parmar
Feb 28 at 12:05
7
@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 thatexpr++is equivalent is detrimental.
– Govind Parmar
Feb 28 at 12:12
3
@SolomonUcko No, the first would dereference the pointer and then increment it. The second would increment the pointer THEN dereference it.
– ale10ander
Feb 28 at 20:21
|
show 6 more comments
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.
7
So for example, if you define a macro#define postinc(x) x++thenpostinc(*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)++)
– Daniel Schepler
Feb 28 at 1:12
10
Your answer boils down to "parenthesis can be used to enforce operator precedence" which is obvious and not what the OP asked.
– Giacomo Alzetta
Feb 28 at 9:53
3
@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.
– Govind Parmar
Feb 28 at 12:05
7
@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 thatexpr++is equivalent is detrimental.
– Govind Parmar
Feb 28 at 12:12
3
@SolomonUcko No, the first would dereference the pointer and then increment it. The second would increment the pointer THEN dereference it.
– ale10ander
Feb 28 at 20:21
|
show 6 more comments
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.
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.
edited Feb 27 at 16:08
answered Feb 27 at 15:19
Govind ParmarGovind Parmar
13k53763
13k53763
7
So for example, if you define a macro#define postinc(x) x++thenpostinc(*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)++)
– Daniel Schepler
Feb 28 at 1:12
10
Your answer boils down to "parenthesis can be used to enforce operator precedence" which is obvious and not what the OP asked.
– Giacomo Alzetta
Feb 28 at 9:53
3
@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.
– Govind Parmar
Feb 28 at 12:05
7
@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 thatexpr++is equivalent is detrimental.
– Govind Parmar
Feb 28 at 12:12
3
@SolomonUcko No, the first would dereference the pointer and then increment it. The second would increment the pointer THEN dereference it.
– ale10ander
Feb 28 at 20:21
|
show 6 more comments
7
So for example, if you define a macro#define postinc(x) x++thenpostinc(*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)++)
– Daniel Schepler
Feb 28 at 1:12
10
Your answer boils down to "parenthesis can be used to enforce operator precedence" which is obvious and not what the OP asked.
– Giacomo Alzetta
Feb 28 at 9:53
3
@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.
– Govind Parmar
Feb 28 at 12:05
7
@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 thatexpr++is equivalent is detrimental.
– Govind Parmar
Feb 28 at 12:12
3
@SolomonUcko No, the first would dereference the pointer and then increment it. The second would increment the pointer THEN dereference it.
– ale10ander
Feb 28 at 20:21
7
7
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)++)– Daniel Schepler
Feb 28 at 1:12
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)++)– Daniel Schepler
Feb 28 at 1:12
10
10
Your answer boils down to "parenthesis can be used to enforce operator precedence" which is obvious and not what the OP asked.
– Giacomo Alzetta
Feb 28 at 9:53
Your answer boils down to "parenthesis can be used to enforce operator precedence" which is obvious and not what the OP asked.
– Giacomo Alzetta
Feb 28 at 9:53
3
3
@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.
– Govind Parmar
Feb 28 at 12:05
@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.
– Govind Parmar
Feb 28 at 12:05
7
7
@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.– Govind Parmar
Feb 28 at 12:12
@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.– Govind Parmar
Feb 28 at 12:12
3
3
@SolomonUcko No, the first would dereference the pointer and then increment it. The second would increment the pointer THEN dereference it.
– ale10ander
Feb 28 at 20:21
@SolomonUcko No, the first would dereference the pointer and then increment it. The second would increment the pointer THEN dereference it.
– ale10ander
Feb 28 at 20:21
|
show 6 more comments
protected by P.W Mar 1 at 5:10
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
18
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.
– Hans Passant
Feb 27 at 16:38
3
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.
– Tomasz Kornuta
Feb 28 at 3:20
1
To be clear, both of these cases are well-defined (i.e., not UB) and will store 3 in
j.– osuka_
Feb 28 at 15:09
1
"am I overthinking it" yes.
– alk
Mar 5 at 20:10