In most real-world situations, an invitation to assume something will happen implies that one is not obligated to take any special measures to allow for the possibility that it doesn't, but is not a license to behave in arbitrary fashion if one discovers that the event in question won't occur.
Under fashionable interpretations of the C Standard, however, there is no reason to expect that implementations will refrain from totally nonsensical fashion if any assumption the Standard would invite them to make proves incorrect.
I don't think the authors of the Standard intended that C compilers would use complicated inference engines which cascade assumptions to the point that a compiler given e.g.
if (x > 1000) foo(x);
while ( x <= 1000)
somethingWithNoSideEffectsThatCantAffectX();
would conclude that foo
should be executed unconditionally regardless of the value of x
. More likely, they intended that a compiler given something like:
volatile int yy;
void test(int x, int *restrict arr)
{
int y;
do
x=arr[x];
while(x & 1);
y=yy;
if (y)
printf("%d\n",x);
}
would be allowed to use the fact that the final value of x
may or may not be needed to rearrange the code to be more efficient in the cases where it isn't (by skipping its calculation altogether). Essentially, the fact that a piece of code takes time to execute--even if infinite--should not be considered a side-effect in and of itself, and if a compiler can prove that a piece of code cannot execute any side-effects that would be visible before it reaches a certain place, it need not wait for that piece of code to finish before executing code at that place.
Unfortunately, the authors of the Standard rely upon compiler writers to recognize what kinds of actions may be usefully taken on the basis of certain assumptions, while compiler writers assume that any possible inference they can draw should be presumed useful.