How Do We Explain the Result of the Expression (++X)+(++X)+(++X)

How do we explain the result of the expression (++x)+(++x)+(++x)?

We explain it by expecting undefined behaviour rather than any particular result. As the expression attempts to modify x multiple times without an intervening sequence point its behaviour is undefined.

Why does (x += x += 1) evaluate differently in C and Javascript?

JavaScript and Java have pretty much strict left-to-right evaluation rules for this expression. C does not (even in the version you provided that has the identity function intervening).

The ECMAScript spec I have (3rd Edition, which I'll admit is quite old – the current version can be found here: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) says that compound assignment operators are evaluated like so:

11.13.2 Compound Assignment ( op= )

The production AssignmentExpression : LeftHandSideExpression @ =
AssignmentExpression, where@ represents one of the operators indicated
above, is evaluated as follows:

  1. Evaluate LeftHandSideExpression.
  2. Call GetValue(Result(1)).
  3. Evaluate AssignmentExpression.
  4. Call GetValue(Result(3)).
  5. Apply operator @ to Result(2) and Result(4).
  6. Call PutValue(Result(1), Result(5)).
  7. Return Result(5)

You note that Java has the same behavior as JavaScript – I think its spec is more readable, so I'll post some snippets here (http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.7):

15.7 Evaluation Order

The Java programming language guarantees that the operands of
operators appear to be evaluated in a specific evaluation order,
namely, from left to right.

It is recommended that code not rely crucially on this specification.
Code is usually clearer when each expression contains at most one side
effect, as its outermost operation, and when code does not depend on
exactly which exception arises as a consequence of the left-to-right
evaluation of expressions.

15.7.1 Evaluate Left-Hand Operand First The left-hand operand of a binary operator appears to be fully evaluated before any part of the
right-hand operand is evaluated. For example, if the left-hand operand
contains an assignment to a variable and the right-hand operand
contains a reference to that same variable, then the value produced by
the reference will reflect the fact that the assignment occurred
first.

...

If the operator is a compound-assignment operator (§15.26.2), then
evaluation of the left-hand operand includes both remembering the
variable that the left-hand operand denotes and fetching and saving
that variable's value for use in the implied combining operation.

On the other hand, in the not-undefined-behavior example where you provide an intermediate identity function:

x += id(x += 1);

while it's not undefined behavior (since the function call provides a sequence point), it's still unspecified behavior whether the leftmost x is evaluated before the function call or after. So, while it's not 'anything goes' undefined behavior, the C compiler is still permitted to evaluate both x variables before calling the id() function, in which case the final value stored to the variable will be 1:

For example, if x == 0 to start, the evaluation could look like:

tmp = x;    // tmp == 0
x = tmp + id( x = tmp + 1)
// x == 1 at this point

or it could evaluate it like so:

tmp = id( x = x + 1);   // tmp == 1, x == 1
x = x + tmp;
// x == 2 at this point

Note that unspecified behavior is subtly different than undefined behavior, but it's still not desirable behavior.

How is the result of the expression (0==0 1 2 3 2 1 0==0) calculated in python?

Unlike most languages, Python supports chained comparisons. So the following:

0==0<1<2<3>2>1>0==0

is equivalent to:

0==0 and 0<1 and 1<2 and 2<3 and 3>2 and 2>1 and 1>0 and 0==0

You can read about it here. The relevant excerpt is:

Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).

Why does x = x * y / z give a different result from x *= y / z for integers?

Because * and / have the same precedence with left associativity, the expression is not

x * ((*n + i) / i)

(which is the same as x *= (*n + i) / i) but

(x * (*n + i)) / i

I can not understand the output of this c programming. Please any one help

|| and && short-circuit. What that means is that they perform as little work as possible to return their value, only executing the right side if the left side doesn't nail the answer.

For instance:

1 || anything();

In this case, anything() will never execute, because || can simply return as soon as it evaluates the 1; no matter what anything()'s return value, the return value of || in this expression can never be 0.

Similarly:

0 && anything_else();

Here, anything_else() will never execute, because && already knows that its value can never be anything but 0.

In your examples, the ++ preincrements don't actually affect the short-circuiting, except to hide the values that the boolean short-circuit operators are actually making their decisions on.

Having problem with solving a problem regarding Statements and Expressions in Java(The statement x = y = x = 0 is illegal??)

a

Take the expression a+1 for instance. This makes no sense as a statement as it does not change anything and is not possible.

b

x++ returns x and increments it afterwards.

As it changes the variable, it can be used as a statement.

c

When you assign a value to something else, it returns the assigned value.

d

This is possible because x=0 sets x to 0 and returns 0.

Then, it sets y to x (0) and returns this value (0).

Then, it sets x to y (0) (and returns this value (0)).

What is the evaluation order of the expression &x- y- z?

First of all, "precedence" doesn't mean order of evaluation . It refers to the association of operands with operators. For example in f() + g() * h(), the three function calls could occur in any order; saying that * has higher precedence is saying that the two operands of * are g() and h(). The compiler might call all three functions, and then multiply the results of the g and h calls, and then add the result of the f call.

In &x->y->z things are easier because the second operand of -> (and .) isn't an expression. It's an identifier that names a class member. So the second operand isn't evaluated, really.

The precedence rules, or grammar table, tells use that the operand of the unary & operator is x->y->z.

To understand x->y->z, clearly it is not the case that we are looking for a member of the struct pointed to by x whose name is "y->z" since that is not a valid identifier. That would not be a valid syntax parse. So it can only mean that ->z is applied to the result of x->y.

how is x&&y||z evaluated?

x && y || z 

is equivalent to

(x && y) || z

if x=1 and y=2
then x&&y is 1 && 2 which is true && true which is true.

true || z 

is always true. z isn't even evaluated



Related Topics



Leave a reply



Submit