Evaluation order for let-array statement

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view

Evaluation order for let-array statement

This post was updated on .
Jack Code:
class Main {
  static Array x, a, b;

  function void main() {
    let a = Array.new(1);
    let b = Array.new(1);
    let a[0] = 10;
    let b[0] = 20;
    let x = a;

    let x[Main.foo()] = 42;  // Line 11

    do Output.printInt(a[0]);
    do Output.printChar(32);
    do Output.printInt(b[0]);
    do Output.println();

  function int foo() {
    let x = b;
    return 0;

Result of supplied JackCompiler: 10 42
Result of my JackCompiler: 42 20

On Line 11, evaluating subscript expression Main.foo() changes where variable x is pointed.
According to Lecture 11 Slide 67, the order should "push x, and then compile subscript expression Main.foo()". If then, I think my JackCompuler implementation is right.

Is there formal specification of Jack language for this case?
More formally, given Jack statement let a[b] = c; among six possible permutation of evaluation order of a, b, and c, what is the "correct" order?
Reply | Threaded
Open this post in threaded view

Re: Evaluation order for let-array statement

This is undefined behavior and not covered by the Jack language specification. Therefore there is no wrong or right here, it is implementation-dependent. Such corner cases - in this case side effects - are typically considered as bad programming style and should be avoided generally due to its semantic ambiguity.

This is not just a Jack-specific topic, it is common in many languages to have undefined behavior. See for example a long list in the draft for the new ISO draft for C programming language under Appendix J.2 pages 579-589.

Edit: A similar case is actually covered by J.1 in the ISO C standard:
Unspecified behavior:
— The order in which subexpressions are evaluated and the order in which side effects take place,
except as specified for the function-call (), &&, ||, ?:, and comma operators (6.5).
— The order in which the function designator, arguments, and subexpressions within the arguments are evaluated in a function call (
— The order of side effects among compound literal initialization list expressions (
— The order in which the operands of an assignment operator are evaluated (6.5.16).