Ответ 1
Оптимизация является законной из-за правила "как есть ", то есть C11 5.1.2.3p6.
Соответствующая реализация требуется только для создания программы, которая при запуске производит такое же наблюдаемое поведение, как и выполнение программы с использованием абстрактной семантики. Остальная часть стандарта описывает только эти абстрактные семантики.
То, что скомпилированная программа делает внутренне, не имеет никакого значения, единственное, что имеет значение, - это то, что когда программа заканчивается, у нее нет другого наблюдаемого поведения, кроме чтения a
и b
и печати значения a + 1
или b + 2
в зависимости от того, какой a
или b
больше, если только что-то не происходит, что приводит к неопределенному поведению. (Плохой ввод приводит к тому, что a, b не инициализируется и, следовательно, обращается к undefined, ошибка диапазона и переполнение подписей также могут возникать.) Если происходит неопределенное поведение, тогда все ставки отключены.
Поскольку доступ к изменчивым переменным должен оцениваться строго в соответствии с абстрактной семантикой, вы можете избавиться от условного перемещения, используя volatile
:
#include <stdio.h>
int main() {
volatile int a, b;
scanf("%d %d", &a, &b);
int c = a > b ? a + 1 : 2 + b;
printf("%d", c);
return 0;
}
компилируется
call [email protected]
movl (%rsp), %edx
movl 4(%rsp), %eax
cmpl %eax, %edx
jg .L7
movl 4(%rsp), %edx
addl $2, %edx
.L3:
leaq .LC1(%rip), %rsi
xorl %eax, %eax
movl $1, %edi
call [email protected]
[...]
.L7:
.cfi_restore_state
movl (%rsp), %edx
addl $1, %edx
jmp .L3
моим GCC Ubuntu 7.2.0-8ubuntu3.2