我正在查看GCC 9.1为新(C ++ 17)函数std :: uninitialized_default_construct生成的程序集。在大多数情况下(MSVC,Clang甚至是较旧的GCC),这就是您所期望的:调用(或内联)类型T的默认构造函数的循环。
由于某些原因,GCC从7到当前以-03运行会生成我不完全了解的程序集。尤其是一开始看起来像哈希的部分。
我正在使用“ -O3 -std = c ++ 17 -fno-stack-protector -fno-exceptions -fomit-frame-pointer -fno-unroll-loops”进行编译。我在这里想念东西吗?
在各种编译器上测试了相同的代码。没有人表现得很奇怪。我没有找到关于哈希的解释。
测试代码(通过godbolt.org运行):
#include <iostream>
#include <algorithm>
#include <memory>
#include <string>
#include <stdio.h>
struct Vector3 {
float x=0,y=0,z=0;
};
template< typename T >
static int init(T* mem, size_t len)
{
std::uninitialized_default_construct(mem, mem+len);
return 0;
}
template< typename T >
static int init2(T* mem, size_t len)
{
auto end = mem + len;
while (mem < end)
new (mem++) T();
return 0;
}
int main(int argc, char** argv)
{
Vector3 mem[100];
auto funcPtr = (argc > 2) ? &init<Vector3> : &init2<Vector3>;
if (0 != funcPtr(mem, (int)atoi(argv[1])))
return -1;
printf("%f\n", mem[0].x);
return 0;
}
函数“ init”的生成反汇编(做好准备):
int init<Vector3>(Vector3*, unsigned long):
lea rax, [rsi+rsi*2]
lea rcx, [rdi+rax*4]
cmp rcx, rdi
je .L2
movabs rsi, 3074457345618258603
mov rdx, rcx
mov rax, rdi
sub rdx, rdi
sub rdx, 12
shr rdx, 2
imul rdx, rsi
movabs rsi, 4611686018427387903
and rdx, rsi
lea rsi, [rdx+1]
cmp rdx, 2
jbe .L3
mov rdx, rsi
pxor xmm0, xmm0
shr rdx, 2
lea rdx, [rdx+rdx*2]
sal rdx, 4
add rdx, rdi
.L4:
movups XMMWORD PTR [rax], xmm0
add rax, 48
movups XMMWORD PTR [rax-32], xmm0
movups XMMWORD PTR [rax-16], xmm0
cmp rax, rdx
jne .L4
mov rax, rsi
and rax, -4
lea rdx, [rax+rax*2]
lea rdi, [rdi+rdx*4]
cmp rsi, rax
je .L2
.L3:
lea rax, [rdi+12]
mov QWORD PTR [rdi], 0
mov DWORD PTR [rdi+8], 0x00000000
cmp rcx, rax
je .L2
lea rax, [rdi+24]
mov QWORD PTR [rdi+12], 0
mov DWORD PTR [rdi+20], 0x00000000
cmp rcx, rax
je .L2
mov QWORD PTR [rdi+24], 0
mov DWORD PTR [rdi+32], 0x00000000
.L2:
xor eax, eax
ret
为进行比较,这是MSVC为相同代码生成的:
int init<Vector3>(Vector3 *,unsigned __int64) PROC ; init<Vector3>, COMDAT
lea rax, QWORD PTR [rdx+rdx*2]
lea rdx, QWORD PTR [rcx+rax*4]
xor eax, eax
cmp rcx, rdx
je SHORT $LN5@init
npad 1
$LL6@init:
mov QWORD PTR [rcx], rax
mov DWORD PTR [rcx+8], eax
add rcx, 12
cmp rcx, rdx
jne SHORT $LL6@init
$LN5@init:
ret 0
有没有办法使GCC正常运行?