为什么像GCC这样的编译器不能对vector做死代码消除?

尝试后,我想知道为什么 GCC 能够在未使用的mallocnew缓冲区上执行 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。


以上是为什么像GCC这样的编译器不能对vector做死代码消除?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>