为什么像GCC这样的编译器不能对vector做死代码消除?
尝试后,我想知道为什么 GCC 能够在未使用的malloc或new缓冲区上执行 DCE而不能在未使用的上执行 DCE vector?
malloc案例:https : //godbolt.org/z/xKx5Y1
void fun() {
int *x = (int *)malloc(sizeof(int) * 100);
}
结果组装:
fun():
ret
fun():
ret
new案例:https : //godbolt.org/z/66drKr
void fun() {
int *x = new int[100];
}
结果组装:
vector案例:https : //godbolt.org/z/TWhE1E
void fun() {
vector<int> x(100);
}
结果组装:
fun():
sub rsp, 8
mov edi, 400
call operator new(unsigned long)
mov esi, 400
lea rdi, [rax+8]
mov rcx, rax
mov QWORD PTR [rax], 0
mov r8, rax
mov QWORD PTR [rax+392], 0
and rdi, -8
xor eax, eax
sub rcx, rdi
add ecx, 400
shr ecx, 3
rep stosq
mov rdi, r8
add rsp, 8
jmp operator delete(void*, unsigned long)
回答
从 C++14 开始,来自new#Allocation:
允许新表达式省略或组合通过可替换分配函数进行的分配。在省略的情况下,编译器可以在不调用分配函数的情况下提供存储(这也允许优化未使用的新表达式)。[..]
请注意,此优化仅在使用 new 表达式时才允许,而不是任何其他调用可替换分配函数的方法:
delete[] new int[10];可以优化,但operator delete(operator new(10));不能。
并且使用的默认分配器使用std::vector后者,因此禁止您建议的优化(因为as-if规则可能仍然适用,但这些运算符可能已被替换,因此很难证明没有副作用) .
如果您提供自定义分配器,您可能会得到预期的优化:Demo。