【问题标题】:`operator delete` with size parameter and without size parameter: which one is chosen when both are available?带大小参数和不带大小参数的`operator delete`:两者都可用时选择哪一个?
【发布时间】:2019-05-29 21:30:51
【问题描述】:

当我在 GCC 和 Clang 中运行此代码示例时

struct S
{
  int a;        

  void *operator new(size_t s) 
  { 
    std::cout << "new " << s << std::endl;
    return ::operator new(s); 
  }

  void operator delete(void *p, size_t s) noexcept 
  { 
    std::cout << "delete " << s << std::endl;
    ::operator delete(p);
  }

  void operator delete(void *p) noexcept
  { 
    std::cout << "delete " << "none" << std::endl;
    ::operator delete(p);
  }
};

int main()
{
  S *p = new S;
  delete p;
}

我从 GCC 和 Clang 得到以下输出

new 4
delete none

这意味着编译器选择了operator delete 的“无大小”版本。

但是,如果我尝试使用全局替换的 operator newoperator delete 函数进行类似的操作

struct S
{
  int a;        
};

void *operator new(size_t s)
{
  std::cout << "new " << s << std::endl;
  return std::malloc(s);
}

void operator delete(void *p, size_t s) noexcept
{
  std::cout << "delete " << s << std::endl;
  std::free(p);
}

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

int main()
{
  S *p = new S;
  delete p;
}

从 GCC 我得到 ​​p>

new 4
delete 4

我从 Clang 得到

new 4
delete none

我知道自 C++98 以来 C++ 中就出现了类内 operator delete 的“大小”版本,但是通过 C++98 看,我似乎无法找到明确的答案在第一个示例中应该选择哪个版本的operator delete 的问题。甚至指定了吗?

在第二个示例中,C++14 及其全局operator delete 的“大小”版本又如何呢?语言是否说明应该选择哪个版本?

【问题讨论】:

    标签: c++ operator-overloading c++14 language-lawyer delete-operator


    【解决方案1】:

    这是CWG issue 255,可以追溯到 2000 年。引用它的前提:

    15.5 [class.free] 的第 4 段谈到查找释放 功能。虽然如果放置解除分配功能是错误的 仅通过此查找找到,似乎有一个假设是 放置释放函数和通常的释放函数可以 两者都在给定的类范围内声明而不会产生歧义。 避免歧义的正常机制 在同一作用域内声明同名是重载决议; 但是,描述中没有提到重载解决方案 的查找。事实上,目前似乎什么都没有 处理这种情况的措辞。也就是出现下面的例子 根据目前的措辞,格式不正确:

    struct S {
        void operator delete(void*);
        void operator delete(void*, int);
    };
    void f(S* p) {
        delete p;    // ill-formed: ambiguous operator delete
    }
    

    问题的状态目前为“草拟”,在撰写此答案时,它似乎仍未解决。没有关于释放函数的重载决议的措辞。

    Clang 和 GCC 似乎是在随意选择。我认为最好发出某种关于操作员模棱两可的诊断。

    【讨论】:

    • operator delete[]无关?
    • @Sandburg - No. operator delete 有一个合法的重载,它接受最派生对象的对象大小作为附加参数。
    • @Sandburg:这两个版本的算子都有关系。
    猜你喜欢
    • 2011-12-11
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    相关资源
    最近更新 更多