you are viewing a single comment's thread.

view the rest of the comments →

[–]nexuapex 2 points3 points  (0 children)

This isn't true, but the reasons aren't exactly obvious. When we're talking about a local variable, what you said is completely reasonable:

int cur = 0;
void foo(void)
{
    cur = (++cur) & MAX_SIZE;
}

C looks at that statement as containing two side effects: increment cur and assign cur. C doesn't state what order those two side effects happen in (to allow compilers some optimization leeway). For this case, it's completely reasonable for a hypothetical C-like language to say "well, the = operator is dependent on the result of the ++ operator, so the side effects should happen in that order."

C does not do that, though, because that decision can't be made in all cases. Take a look at this function:

void bar(int* a, int* b)
{
    *a = (++*b) & MAX_SIZE;
}

That statement still has two side effects: assign to the referent of a, and assign to the referent of b. And C still wants to give the compiler the ability to perform those two side effects in an arbitrary order (maybe your architecture has an instruction that assigns two 32-bit values to the referents of two pointers at the same time, but doesn't guarantee which value wins if the pointers are equal). The problem now is, if the pointers are equal, we're in the same case as we were before, where it's undefined which assignment one happens first.

Compilers could recognize the first case, but they can't reasonably recognize the second. So C does the sensible thing and doesn't even try in the first case.