Короткое замыкание логических операндов без побочных эффектов

Для награды: Как можно отключить это поведение в каждом конкретном случае, не отключая или не понижая уровень оптимизации?

Следующее условное выражение было скомпилировано на 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, который требует, чтобы логические операторы выполняли короткое замыкание, как только можно определить результат?

7
задан Unsigned 27 September 2011 в 02:29
поделиться