What could be the reason for not defining the order of execution?
The reason is myopia: making it easy to write optimizing compilers,
at the cost of introducing risk into the code-base written in the programming
language.
Undefined orders of execution have no place in an imperative programming
language; i.e. one in which the majority of programs that are considered
idiomatic do their job by means of side effects in expressions.
If you were designing a C-like language from scratch today, and left
evaluation order undefined, you should be shot.
What benefit it provides ? is it the speed?
The belief that it provides speed is not a fact.
Even if evaluation order is well-defined, compilers can still rearrange the
evaluation, provided that the result of the computation is correct.
Only in cases where there are side effects does the order have to be
sufficienty constrained so that the effects are done in the proper order.
Note that C does define the order among full expressions, with the concept of
sequencing.
Any compiler that literally obeys sequence points cannot be called optimizing
by modern standards. A quality compiler must reorder computation across
sequence points! So if you write
x = a + b;
y = a + z;
even though there is a sequence point between these expressions,
they can be reordered, because they are independent. Even
these could be significantly rearranged:
a = i++;
b = i++;
The generated code could do something like
a = i;
b = i + 1;
i += 2;
Sequencing doesn't mean that the computation must literally take place as
written in every detail; it's an abstract concept tied to the ``as if'' rule.
Even if it can be shown than unspecified order of evaluation provides an
undeniable performance benefit, there is no reason why that order has to be
unspecified in every part of the program, in every expression in every function
in every source file.
If unspecified evaluation order is indeed an optimization tool, then it should
be recognized that it's a dangerous optimization tool, and a way should be
provided for the programmer to choose the regions of the program where the
order is unspecified. Suppose you had a reorder operator:
reorder /expression/
Everything under the reorder operator is subject to unspecified evaluation
order, other than sequencing operators. The return value and type of the
reorder operator are those of the expression.