В большинстве реальных ситуаций приглашение предполагать, что что-то произойдет, подразумевает, что человек не обязан принимать какие-либо специальные меры, чтобы допустить вероятность того, что это произойдет, но не является лицензией на произвольное поведение, если обнаруживается, что данное событие не произойдет.
В модных интерпретациях стандарта C, однако, нет оснований ожидать, что реализации будут воздерживаться от абсолютно бессмысленной манеры, если какое-либо предположение, согласно которому Стандарт заставит их сделать это, окажется неверным.
Я не думаю, что авторы Стандарта предполагали, что компиляторы C будут использовать сложные механизмы вывода, которые каскадно предполагают, что компилятор дает, например,
if (x > 1000) foo(x);
while ( x <= 1000)
somethingWithNoSideEffectsThatCantAffectX();
сделает вывод, что foo
должен выполняться безоговорочно, независимо от значения x
. Скорее всего, они намеревались дать компилятору что-то вроде:
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);
}
будет разрешено использовать тот факт, что окончательное значение x
может или не может потребоваться для перестройки кода, чтобы сделать его более эффективным в тех случаях, когда это не так (пропуская его вычисления вообще). По сути, тот факт, что выполнение части кода занимает время - , даже если оно бесконечно - не должен рассматриваться как побочный эффект сам по себе, и если компилятор может доказать, что часть кода не может выполнить какие-либо побочные эффекты, которые были бы видимы, прежде чем он достигнет определенного места, ему не нужно ждать завершения этого куска кода, прежде чем выполнять код в этом месте.
К сожалению, авторы Стандарта полагаются на авторов компиляторов, чтобы распознать, какие действия могут быть полезны на основе определенных предположений, в то время как авторы компиляторов предполагают, что любой возможный вывод, который они могут сделать, должен считаться полезным.