简体   繁体   中英

adding variable to itself with postfix increment different in Java/c# than in C

In Java and C# if I do this:

int i=1;
int j= i++ + i;

j is 3, ie it translates to 1+2 and increments i before the addition.

However, in C j is 2, ie it translates to 1+1 then increments i.

What is the internal mechanism in C and Java/C# that causes this difference in what an expression is?

(the same goes for post-fix. Java/C# become 4 and C becomes 3.)

thanks.

Btw, initially I assumed it would be what the C answer was and so was confused by the Java/C# result.

Unlike Java and C# which specify precisely when the side effects would take place, C prohibits the use of an expression with side effects before the next sequence point . Not only does your expression produce a different result in C, but it is also undefined behavior.

In C, the mechanism is a finely-tuned celebration of compiler-writing skills affectionally known as Undefined behavior , or "UB".

In other words, nobody can provide an answer for C, since the code is known in advance to trigger undefined behavior. Anything could happen, there's no "right" or "wrong".

From the 2011 draft of the C language standard :

6.5 Expressions

...
2 If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings. 84)

3 The grouping of operators and operands is indicated by the syntax. 85) Except as specified later, side effects and value computations of subexpressions are unsequenced. 86)
84) This paragraph renders undefined statement expressions such as
\n    i = ++i + 1; \n    a[i++] = i; \n
while allowing
\n    i = i + 1; \n    a[i] = i; \n

85) The syntax specifies the precedence of operators in the evaluation of an expression, which is the same as the order of the major subclauses of this subclause, highest precedence first. Thus, for example, the expressions allowed as the operands of the binary + operator (6.5.6) are those expressions defined in 6.5.1 through 6.5.6. The exceptions are cast expressions (6.5.4) as operands of unary operators (6.5.3), and an operand contained between any of the following pairs of operators: grouping parentheses () (6.5.1), subscripting brackets [] (6.5.2.1), function-call parentheses () (6.5.2.2), and the conditional operator ? : (6.5.15). Within each major subclause, the operators have the same precedence. Left- or right-associativity is indicated in each subclause by the syntax for the expressions discussed therein.

86) In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations.

The order in which the side effect of i++ is applied relative to the larger expression i++ + i is unspecified ; the two operations are unsequenced relative to each other. If the side effect is applied immediately after i++ is evaluated, then you'll get the result of 1 + 2. If the side effect is deferred until after the addition, you'll get the result of 1 + 1.

The older version of the standard was a bit clearer; an object may have its value modified at most once by the evaluation of an expression between sequence points, and the prior value of the expression is used only to determine the new value to be stored.

The behavior is left undefined so that the compiler isn't required to detect these issues and issue a diagnostic ( i++ + i is easy enough to catch, but there are far more subtle variations of this problem that are a lot harder to detect). Either result is "correct" as far as the language definition is concerned.

In C, post increment/decrement will be executed after the current operation is done. in this example, i++ + i; i will be incremented after the addition is done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM