В следующем случае разрешено ли компилятору оптимизировать вызов foo()
и \ или весь if
блок?
if( foo() && 0 )
{ ... }
С точки зрения стандартов, компилятор должен оцените левую сторону, т.е. foo()
должен называться:
[C99, 6.5.13] В отличие от побитового двоичного
&
оператор,&&
оператор гарантирует оценку слева направо;
после оценки первого операнда есть точка последовательности. Если первый операнд
сравнивается равным 0, второй операнд не оценивается.
Но так как он знает, что тело if
заявление никогда не может быть достигнуто,* тогда можно свободно пропустить любой соответствующий код для этой части.
Конечно, если компилятор может доказать, что foo()
не имеет видимых побочных эффектов, тогда он также может оптимизировать этот вызов. Но это не имеет ничего общего с поведением короткого замыкания.
* (Только C ++) при условии foo()
не возвращает тип с перегрузкой operator&&
,
Компилятор должен выполнить foo
прежде чем определить, что 0
означает утверждение в if
не выполнен Однако если foo
это очень простая функция, которая не имеет побочных эффектов (не изменяет ни одно глобальное состояние — и в стандартах C и C ++ ее есть длинное определение), а затем сама может быть оптимизирована. Обычно это происходит только в том случае, если foo
является частью того же исходного кода.
эквивалентный код:
int x = (int) foo();
if (x)
if (0)
{ ... }
Вы можете «оптимизировать» первую строку для произвольного foo? foo
может быть что-то вроде
int foo() {
printf("x");
return 0;
}