Order of evaluation in assignment statements

98 Views Asked by At

The Ada 2012 standard says:

For the execution of an assignment_statement, the variable_name and the expression are first evaluated in an arbitrary order.

I am wondering how far reaching that statement is. If both the right hand side and the left hand side of an assignment contains subprogram calls, can those calls be made in arbitrary order, or will all the left hand side be evaluated before/after all the calls of the right hand side?

E.g. if I have Arr(L1(X), L2(X)) := Arr(R1(Y), R2(Y)), can I be sure that the call order will be one of:

  1. L1, L2, R1, R2
  2. L1, L2, R2, R1
  3. L2, L1, R1, R2
  4. L2, L1, R2, R1
  5. R1, R2, L1, L2
  6. R1, R2, L2, L1
  7. R2, R1, L1, L2
  8. R2, R1, L2, L1

Or could the calls on the left hand side and the right hand side be mixed, such as: L1, R2, L2, R2?

4

There are 4 best solutions below

2
Jere On

My interpretation of the reading is that it wouldn't mix them and instead use one of your 8 options above. However, I couldn't find any specific wording to confirm or deny that. If no one else is able to answer definitively, I would recommend creating an issue at the Ada Rapporteur Group github and seek clarification on the ARM wording. You might be able to get a more definitive answer there

https://github.com/Ada-Rapporteur-Group/User-Community-Input/issues

2
Zerte On

As long as the functions don't have side effects it should not matter. Plus, optimizing compilers (GNAT for instance) will certainly do better than calling L1, L2, R1, R2 separately (in any order), if it is possible.

0
Jeffrey R. Carter On

the variable_name and the expression are first evaluated in an arbitrary order.

This wording means the order is one of

  1. The variable_name is evaluated first, then the expression, or
  2. The expression is evaluated first, then the variable_name

If the compiler can prove it is equivalent to one of those orders, they may also be evaluated in parallel.

2
Jim Rogers On

Of course you can always control the call order in your source code by eliminating shortcuts.

Given your example:

Arr(L1(X), L2(X)) := Arr(R1(Y), R2(Y))

You can specify the order as in the example below forcing the evaluation to be in the order of R1, R2, L1, L2.

R1_Index := R1(Y);
R2_Index := R2(Y);
L1_Index := L1(X);
L2_Index := L2(X);
Arr(L1_Index, L2_Index) := Arr(R1_Index, R2_Index);