static constexpr int
count_x(const char * str)
{
int count{};
for (;*str != 0; ++str) {
count += *str == 'x';
}
return count;
}
#define STRx1 "123456789x"
#define STRx4 STRx1 STRx1 STRx1 STRx1
#define STRx8 STRx4 STRx4
#define STRx16 STRx8 STRx8
int test1() { return count_x(STRx4); }
int test2() { return count_x(STRx8); }
int test3() { return count_x(STRx16); }
int test4() { constexpr auto k = count_x(STRx16); return k; }
Учитывая приведенный выше код, clang выдает постоянное значение для test1, test2 и test4.Почему не для test3?
test1(): # @test1()
mov eax, 4
ret
test2(): # @test2()
mov eax, 8
ret
test3(): # @test3()
xor eax, eax
mov dl, 49
mov ecx, offset .L.str.2+1
.LBB2_1: # =>This Inner Loop Header: Depth=1
xor esi, esi
cmp dl, 120
sete sil
add eax, esi
movzx edx, byte ptr [rcx]
add rcx, 1
test dl, dl
jne .LBB2_1
ret
test4(): # @test4()
mov eax, 16
ret
.L.str.2:
.asciz "123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x"
gcc делает:
test1():
mov eax, 4
ret
test2():
mov eax, 8
ret
test3():
mov eax, 16
ret
test4():
mov eax, 16
ret
Используемые командные строки компиляции:
clang++ -Ofast -std=c++2a -S -o - -c src/test.cpp | grep -Ev $'^\t+\\.'
gcc9 -Ofast -std=c++2a -S -o - -c src/test.cpp | grep -Ev $'^\t+\\.'
Проводник компилятора: https://godbolt.org/z/V-3MEp