Некоторые люди пишут такой код, когда им нужен цикл без счетчика или с n-1, ..., 0
счетчиком:
while (i--) { ... }
Конкретный пример:
volatile int sink;
void countdown_i_used() {
unsigned i = 1000;
while (i--) {
sink = i; // if i is unused, gcc optimizes it away and uses dec/jnz
}
}
В GCC 8.2 ( в проводнике компилятора Godbolt ) он компилируется в
# gcc8.2 -O3 -march=haswell
.L2:
mov DWORD PTR sink[rip], eax
dec eax # with tune=generic, sub eax, 1
cmp eax, -1
jne .L2
On clang (https://godbolt.org/z/YxYZ95),, если счетчик не используется, он превращается в
if(i) do {...} while(--i);
но если используется, как GCC, он превращается в
add esi, -1
cmp esi, -1
jnz lp
Однако, это, кажется, лучшая идея:
sub esi, 1
jnc lp
Почему эти два компилятора не используют этот способ?
Потому что способ cmp
лучше? Или потому, что они не будут экономить место таким образом и будут иметь почти одинаковую скорость?
Или они просто не рассматривают этот вариант?