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

Why compiler like GCC can not do dead code elimination on vector?

尝试后,我想知道为什么 GCC 能够在未使用的 mallocnew 缓冲区上执行 DCE,但不能在未使用的 vector 上执行 DCE?

malloc 案例:https://godbolt.org/z/xKx5Y1

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

生成的程序集:

fun():
        ret

new 案例:https://godbolt.org/z/66drKr

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

生成的程序集:

fun():
        ret

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)

嗯,仅仅因为 vector 是一个 class。 换句话说,一个可能很复杂的软件对象。当您实例化它的一个实例时,必须调用它的“构造函数”。发生了很多应用程序程序员 故意 不想考虑的事情 – 但是必须生成执行此操作的目标代码。

自 C++14 起,来自 new#Allocation:

New-expressions are allowed to elide or combine allocations made through replaceable allocation functions. In case of elision, the storage may be provided by the compiler without making the call to an allocation function (this also permits optimizing out unused new-expression). [..]

Note that this optimization is only permitted when new-expressions are used, not any other methods to call a replaceable allocation function: delete[] new int[10]; can be optimized out, but operator delete(operator new(10)); cannot.

并且默认的 allocator used by std::vector uses the latter, so your suggested optimization is forbidden (since the as-if 规则可能仍然适用,但这些运算符可能已被替换,因此更难证明没有副作用)。

如果您提供自定义分配器,您可能会进行预期的优化:Demo