Сегодня я начал играть с ветвлением, которая проверяет наличие двух булевых элементов. Я был уверен, что на каком-то уровне оптимизации они просто добавятся, а затем будут проверены, но это не так с gcc и clang. Почему gcc не оптимизирует две проверки bool, заменяя их добавлением и одной проверкой? Позвольте мне показать вам пример:Почему, если проверка не оптимизирована
void test(bool a, bool b)
{
// Branch 1
if (a && b)
{
std::cout << "Branch 1";
}
// Branch 2
if (static_cast<int>(a) + static_cast<int>(b))
{
std::cout << "Branch 2";
}
}
GCC (даже с максимальным уровнем оптимизации) генерирует следующий код для филиала 1:
test dil,dil
je 400794 <test(bool, bool)+0x14>
test sil,sil
jne 4007b0 <test(bool, bool)+0x30>
в то время как он генерирует следующий код для ветви 2:
movzx ebx,bl
movzx ebp,bpl
add ebx,ebp
jne 4007cf <test(bool, bool)+0x4f>
Не должно быть двух ветвей (test + je) медленнее, чем добавление и ветвь (добавить + jne)?
Редактировать: то, что я на самом деле имел в виду, было умножением, потому что в случае сложения true и false (1 + 0) дает true (1), но умножение дает правильный результат (0).
Я не забыл об этом, но как это повлияло на мой код? –
Для начала добавление не '&&', это '||'. Кроме того, хотя и не уверен в текущем стандарте C++, но представление используется как '0' для' false' и все остальное для 'true'. Таким образом, вы могли бы иметь «-1» и «+ 1» для двух истинных значений, и добавление их было бы не очень хорошим. Точно так же вы могли бы иметь «1» и «2», а побитовые «и» не были бы хороши для них. – Jester
@Jester: переменные 'bool' для C++ могут быть только« true »или' false' (I * think *, что верно и для значений C 'bool'.) При преобразовании в' int', они * должны * конвертировать в 1 или 0 соответственно. –