I have this piece of code to loop over a std::array<int, 3>
(see on Compiler Explorer) and find if an element is in the array.
#include <algorithm>
#include <iterator>
#include <array>
constexpr std::array<int, 3> arr = { 0, 1, 2};
bool forLoop(int inp)
{
for (int i {0}; i < arr.size(); ++i)
{
if (arr[i] == inp)
{
return true;
}
}
return false;
}
bool forEachLoop(int inp)
{
for (int i : arr)
{
if (i == inp)
{
return true;
}
}
return false;
}
bool STL(int inp)
{
return std::find(arr.begin(), arr.end(), inp) != arr.end();
}
Compile with x86-64 clang 15.0.0
and -std=c++17 -O3
, both forLoop()
and forEachLoop()
generates:
cmp edi, 3
setb al
ret
But STL()
generates much different assembly
test edi, edi
je .LBB2_1
cmp edi, 1
jne .LBB2_3
lea rax, [rip + arr+4]
lea rcx, [rip + arr+12]
cmp rax, rcx
setne al
ret
.LBB2_1:
lea rax, [rip + arr]
lea rcx, [rip + arr+12]
cmp rax, rcx
setne al
ret
.LBB2_3:
xor eax, eax
cmp edi, 2
setne al
lea rcx, [rip + arr]
lea rax, [rcx + 4*rax]
add rax, 8
lea rcx, [rip + arr+12]
cmp rax, rcx
setne al
ret
I tried using gcc
instead and STL()
still generates a much longer assembly
When I tried to change it so that arr
has other numbers of elements (eg. 4), both 3 functions generates the same assembly.
So is it a missed optimization problem? Why does it happen only on 3 elements?