Я играл с разработчиком компилятора и обнаружил, что эти 2 функции генерируют разные сборки как в gcc, так и в clang. Я ожидал, что после инкрустации они будут производить одинаковые деревья выражений и, следовательно, идентичные и оптимальные сборки.Является ли это причудой оптимизаторов или результатом языковых правил, запрещающих оптимизацию?
constexpr bool is_nonzero_decimal_digit(char const c) noexcept
{
return c == '1' || c == '2' || c == '3' || c == '4' || c == '5'
|| c == '6' || c == '7' || c == '8' || c == '9';
}
bool is_decimal_digit_v1(char const c) noexcept
{
return c == '0' || is_nonzero_decimal_digit(c);
}
bool is_decimal_digit_v2(char const c) noexcept
{
return c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
|| c == '5' || c == '6' || c == '7' || c == '8' || c == '9';
}
Clang 3.9.1 -std = C++ 1z -O3 результат
is_decimal_digit_v1(char):
cmp dil, 48
sete cl
add dil, -49
cmp dil, 9
setb al
or al, cl
ret
is_decimal_digit_v2(char):
add dil, -48
cmp dil, 10
setb al
ret
GCC 6.3 -std = C++ 1z -O3 результат
is_decimal_digit_v1(char):
cmp dil, 48
je .L3
sub edi, 49
cmp dil, 8
setbe al
ret
.L3:
mov eax, 1
ret
is_decimal_digit_v2(char):
sub edi, 48
cmp dil, 9
setbe al
ret
Итак, это причуда оптимизаторов или результат языковых правил, запрещающих оптимизацию?
Предположительно, пропуск, который объединил сравнения OR'd в одно вычитание + сравнение, прогонял перед проходом вложения. –
[Снимки gcc 7.0 оптимизируют их в один и тот же код] (https://godbolt.org/g/iPXtEi). Я думаю, что T.C. верно. – Cornstalks