重载 operator delete 而不重载 new 时的正确行为是什么?gcc 和 clang 不同

Ami*_*rsh 5 c++ gcc operator-overloading clang overload-resolution

以下代码与clang(x86_64-pc-linux-gnu 上的版本 5.0.0-3~16.04.1)和gcc (9.2.0) 的行为不同。

void operator delete(void* ptr) noexcept {
    std::cout << "overloaded delete" << std::endl;
    free(ptr);
}

int main() {
    int* pint = new int;
    delete pint; // clang doesn't go through overloaded operator delete, gcc does
}
Run Code Online (Sandbox Code Playgroud)

gcc通过重载,operator deleteclang避免它更喜欢global delete.

(当添加重载时,operator new两个编译器都同意并通过两个重载版本)。

代码:http : //coliru.stacked-crooked.com/a/0903bd53a8c04a9b

wal*_*nut 1

编译器可以优化分配并完全new省略对全局可替换operator news 和operator deletes 的调用,即使它们有副作用,请参阅C++17 的[expr.new]/10[expr.delete]/7.1标准草案。


如果您在没有该-O2标志的情况下进行编译,您将看到两个编译器都打印出消息,并且 gcc trunk 也会忽略启用优化的分配。


如果编译器没有删除分配/释放函数调用,我会假设你operator delete有未定义的行为,因为你不能保证你正在传递的指针是由它分配的,malloc并且调用free它有未定义的行为(如果不是) 。

您需要始终替换operator newoperator delete