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

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












47















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?










share|improve this question



















  • 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















47















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?










share|improve this question



















  • 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













47












47








47


4






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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 in j.

    – osuka_
    Feb 28 at 15:09






  • 1





    "am I overthinking it" yes.

    – alk
    Mar 5 at 20:10












  • 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







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












2 Answers
2






active

oldest

votes


















89














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.






share|improve this answer




















  • 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



















49














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.






share|improve this answer




















  • 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






  • 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 that expr++ 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









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









89














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.






share|improve this answer




















  • 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
















89














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.






share|improve this answer




















  • 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














89












89








89







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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













  • 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














49














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.






share|improve this answer




















  • 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






  • 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 that expr++ 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















49














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.






share|improve this answer




















  • 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






  • 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 that expr++ 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













49












49








49







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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++ 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





    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 that expr++ 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





    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





    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 that expr++ 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





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?


Popular posts from this blog

Peggy Mitchell

Palaiologos

The Forum (Inglewood, California)