Для вознаграждения: Как это поведение можно отключить в каждом конкретном случае без отключения или снижения уровня оптимизации?
Следующее условное выражение было скомпилировано в MinGW GCC 3.4.5, где a
имеет тип signed long
, а m
имеет тип unsigned long
.
if (!a && m > 0x002 && m < 0x111)
CFLAGS
были использованы -g -O2
. Вот соответствующий вывод сборки GCC (сбрасывается с objdump
)
120: 8b 5d d0 mov ebx,DWORD PTR [ebp-0x30]
123: 85 db test ebx,ebx
125: 0f 94 c0 sete al
128: 31 d2 xor edx,edx
12a: 83 7d d4 02 cmp DWORD PTR [ebp-0x2c],0x2
12e: 0f 97 c2 seta dl
131: 85 c2 test edx,eax
133: 0f 84 1e 01 00 00 je 257 <_MyFunction+0x227>
139: 81 7d d4 10 01 00 00 cmp DWORD PTR [ebp-0x2c],0x110
140: 0f 87 11 01 00 00 ja 257 <_MyFunction+0x227>
120
- 131
можно легко отследить как первую оценку !a
, а затем оценку m > 0x002
. Первый условный переход не происходит до 133
. К этому времени были вычислены два выражения, независимо от результата первого выражения: !a
. Если a
было равно нулю, выражение можно (и нужно) заключить немедленно, что здесь не делается.
Как это относится к стандарту C, который требует от логических операторов короткого замыкания, как только может быть определен результат?