c++ 为什么像GCC这样的编译器不能在向量上做死码消除?[duplicate]

wwodge7n  于 2023-03-09  发布在  其他
关注(0)|答案(2)|浏览(135)

此问题在此处已有答案

Optimization of raw new[]/delete[] vs std::vector(1个答案)
两年前关闭了。
在尝试之后,我想知道为什么GCC能够在未使用的mallocnew缓冲区上执行DCE,而不能在未使用的vector上执行DCE?
malloc用例:https://godbolt.org/z/xKx5Y1

void fun() {
    int *x = (int *)malloc(sizeof(int) * 100);
}

产生的组件:

fun():
        ret

new shell :https://godbolt.org/z/66drKr

void fun() {
    int *x = new int[100];
}

产生的组件:

fun():
        ret

vector shell :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)
wribegjk

wribegjk1#

自C++14起,从新#分配:
允许新表达式省略或合并通过可替换分配函数进行的分配。在省略的情况下,编译器可以提供存储空间,而不调用分配函数(这也允许优化掉未使用的新表达式)。
注意,这种优化仅在使用new-expression时才被允许,而不是使用任何其他方法来调用可替换的分配函数:delete[] new int[10];可以被优化掉,但是operator delete(operator new(10));不能。
std::vector使用的默认allocator使用后者,因此您建议的优化被禁止(因为 * as-if * 规则可能仍然适用,但那些操作符可能已经被替换,因此很难证明没有副作用)。
如果提供自定义分配器,可能会得到预期的优化:Demo .

s3fp2yjn

s3fp2yjn2#

好吧,仅仅因为vector是一个 * 类 *。换句话说,一个可能很复杂的软件对象。当你示例化它的一个示例时,它的“构造函数”必须被调用。很多事情发生了,应用程序员 * 故意 * 不想去想--但是,尽管如此,完成这些事情的对象代码必须被生成。

相关问题