Обычная оптимизация использования условного перемещения (сборка cmov
) для оптимизации условного выражения ?:
C. Однако в стандарте C говорится:
Вычисляется первый операнд; существует точка последовательности между ее оценкой и оценкой второго или третьего операнда (в зависимости от того, что оценивается). Второй операнд оценивается только в том случае, если первый сравнивает не равный 0; третий операнд оценивается только в том случае, если первый сравнивается с 0; результатом является значение второго или третьего операнда (в зависимости от того, что оценивается), преобразованного в тип, описанный ниже.110)
Например, следующий код C
#include <stdio.h>
int main() {
int a, b;
scanf("%d %d", &a, &b);
int c= a > b ? a + 1 : 2 + b;
printf("%d", c);
return 0;
}
будет генерировать оптимизированный связанный код asm следующим образом:
call __isoc99_scanf
movl (%rsp), %esi
movl 4(%rsp), %ecx
movl $1, %edi
leal 2(%rcx), %eax
leal 1(%rsi), %edx
cmpl %ecx, %esi
movl $.LC1, %esi
cmovle %eax, %edx
xorl %eax, %eax
call __printf_chk
В соответствии со стандартом условное выражение будет иметь только одну ветвь. Но здесь оцениваются обе ветки, что противоречит стандартной семантике. Эта оптимизация против стандарта C? Или у многих оптимизаторов компилятора есть что-то несовместимое с языковым стандартом?