Increment in index expression, bug or not

Hello Octave community

I’m wondering whether the following is expected behaviour or a bug:

octave:1> a=[1,1];i=1;b=a(i++)=5
b = 5
octave:2> a
a =

5 1

octave:3> i
i = 2
octave:4> a=[1,1];i=1;b=a(++i)=5
b = 5
octave:5> a
a =

1 5

octave:6> i
i = 2

Evaluations (1) and (4) are identical except for the increment operator of the index expression: Post-increment (1) vs. pre-increment (4). The resulting variable ‘a’ reflects the difference (correctly) but the resulting variable ‘b’ is the same in both evaluations (not correct IMHO). When the index expression is (re-)accessed for the last assignment, shouldn’t it use the post-incremented value of ‘i’?

Thanks for reviewing the example, --vk

I suspect that the “effective” assignment for the post-increment case is something like b=a(i)=5 after which i is increased by one.
Matlab doesn’t have inplace increment operators. What does C do with such expressions?

Hi vk_atlantis23.com

That happens because there have to consider the operators precedence in GNU Octave.

When you’re making those commands, firstly as mmuetzel said before, octave computes ‘()’ access
operator and then the increment operator.

To se better how is the operators precedence in Octave, see the Octave’s manual

Regards!

In C:

#include <stdio.h>

int main()
{
    int i = 0;
    int a[2] = {1,1};
    int b = a[i++] = 5;

    printf("a[0]=%d\na[1]=%d\nb=%d\ni=%d\n", a[0], a[1], b, i);

    return 0;
}

Output:

a[0]=5
a[1]=1
b=5
i=1

And with pre-increment:

#include <stdio.h>

int main()
{
    int i = 0;
    int a[2] = {1,1};
    int b = a[++i] = 5;

    printf("a[0]=%d\na[1]=%d\nb=%d\ni=%d\n", a[0], a[1], b, i);

    return 0;
}

Output:

a[0]=1
a[1]=5
b=5
i=1

So that is comparable with what Octave is doing.

1 Like

Operator precedence does not necessarily correspond to the order of evaluation.
Otherwise, why would the post-increment operators appear before the pre-increment operators in that listing?

(Tbh, I’m not exactly sure why the order in that listing is as it is…)

In the table, there is no ordering within a given level of priority. For example, addition and subtraction have the same precedence level. They are listed as '+', '-' but could equally be listed as '-', '+'. The actual order of execution will depend on how they appear in the Octave expression. In this case, both of these operators group left to right so it will be the first encountered operator that is executed first.

x + y - z === (x + y) - z

My confusion came from this expression: b=a(i++)=5

Clearly, the assignment (to b) is done before incrementing i. But = appears much lower in that listing than the postfix ++

But “order of precedence” and “order of evaluation” seem to be orthogonal.
See also for C:
C Operator Precedence - cppreference.com
Order of evaluation - cppreference.com

Okay, I see the confusion now. The postfix operators have high precedence which means they are considered for evaluation early, but the postfix operator itself is effectively evaluated after the statement has completed.

For example,

x = 1;
y = 1 + x++

Because ++ has the highest precedence it is evaluated first. It effectively expands into two expressions

y = 1 + x
x = x + 1

Then + is higher precedence than = so

y = (1 + x)
=> y = (1 + 1)
=> y = 2

Finally, assignment = is the only operator left.

After that, the effectively created statement x = x + 1 is run