【问题标题】:What's the right behavior when overloading operator delete without overloading new? gcc and clang differ重载运算符 delete 而不重载 new 时正确的行为是什么? gcc 和 clang 不同
【发布时间】:2019-12-17 11:29:30
【问题描述】:

以下代码在 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
}

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

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

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

【问题讨论】:

  • 对于信息,MSVC 也可以通过您的过载(Visual Studio 中的clang-cl 不会)。

标签: c++ gcc clang operator-overloading overload-resolution


【解决方案1】:

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


如果您在不使用-O2 标志的情况下进行编译,您将看到使用编译器和 gcc 主干打印的消息也会省略启用优化的分配。


如果编译器没有删除分配/释放函数调用,我会假设您的 operator delete 具有未定义的行为,因为您无法保证您传递的指针是由 malloc 分配并调用 @如果不是,则 987654330@ 具有未定义的行为。

您需要始终替换 operator newoperator delete

【讨论】:

  • 优化!!多么初级:-) 是的,当我打印获得的地址时,clang 放弃了优化:coliru.stacked-crooked.com/a/5a5ce3408e11db7d
  • > 您需要始终替换 operator newoperator delete。它是规范要求的吗?你能只重载operator new吗?
  • @AmirKirsh 浏览标准我没有看到任何直接需要它的东西,但正如我所提到的,如果你不替换 operator new 以及,你不知道指针如果你不知道它是如何分配的,那么你就不知道如何释放它,违反了释放函数释放指针指向的内存块的要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 2013-03-12
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多