When compiling the following code snippet (clang x86-64 -O3
)
std::array<int, 5> test()
{
std::array<int, 5> values {{0, 1, 2, 3, 4}};
return values;
}
It produced the typical assembly that I would expect
test(): # @test()
mov rax, rdi
mov ecx, dword ptr [rip + .L__const.test().values+16]
mov dword ptr [rdi + 16], ecx
movups xmm0, xmmword ptr [rip + .L__const.test().values]
movups xmmword ptr [rdi], xmm0
ret
.L__const.test().values:
.long 0 # 0x0
.long 1 # 0x1
.long 2 # 0x2
.long 3 # 0x3
.long 4 # 0x4
However for small arrays, it seems to have figured out a trick?
std::array<int, 3> test()
{
std::array<int, 3> values {{0, 1, 2}};
return values;
}
This was the corresponding assembly
test(): # @test()
movabs rax, 4294967296
mov edx, 2
ret
Where did that magic number (4294967296
) come from? Is that essentially a value that can be reinterpret_cast
back into an array of int
somehow?
4294967...
being about 2^32 and thus a huge clue that you should look at the hex to see the upper/lower 32 bits. (Or for numbers just below 2^32, that it's actually a negative 32-bit integer.) – Unwitting