尽管构造函数被标记为noexcept,但GCC仍会产生隐藏的delete运算符调用 [英] GCC produces hidden delete operator call, despite the constructor being marked as noexcept

查看:75
本文介绍了尽管构造函数被标记为noexcept,但GCC仍会产生隐藏的delete运算符调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

某些C ++类已重载了new operator,并且同时不应从外部随意调用delete.所以我保护了这个删除操作符.另外,我用noexcept modern C ++关键字标记了所有类构造函数,以便编译器不会产生调用delete()的异常处理代码.但是用gcc编译时还是会发生!在我的新运算符被调用的行上,它给出了以下错误:

Some C++ class has overloaded new operator and in the same time the delete should not be called freely from an outside. So I protected this delete operator. Also, I marked all class constructors with noexcept modern C++ keyword in order the compiler will not produce an exception handling code calling delete(). But it still happens when compiling by gcc! It gives the following error on the line where my new operator is called:

error: ‘static void MyClass::operator delete(void*)’ is protected

我在Ubuntu上具有gcc版本5.4.0 20160609.通常在VS-2017下编译相同的代码.

I have gcc version 5.4.0 20160609 on my Ubuntu.The same code is normally compiled under VS-2017.

请帮助.如何正确保护删除?

Please help. How can you correctly protect the delete?

推荐答案

来自 expr .new :

如果上述对象初始化的任何部分因引发异常而终止,并且可以找到合适的释放函数,则调用释放函数以释放正在构造对象的内存,此后异常继续传播在new-expression的上下文中. 如果找不到明确的匹配释放函数,则传播异常不会导致对象的内存被释放. [注意:当被调用的分配函数未分配内存时,这是适当的;否则,很可能导致内存泄漏. —尾注]

If any part of the object initialization described above terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called to free the memory in which the object was being constructed, after which the exception continues to propagate in the context of the new-expression. If no unambiguous matching deallocation function can be found, propagating the exception does not cause the object's memory to be freed. [ Note: This is appropriate when the called allocation function does not allocate memory; otherwise, it is likely to result in a memory leak. — end note ]

实际上,这并不意味着如果找不到匹配的释放函数::operator delete,则应触发OP观察到的编译错误.

In fact, this does not imply that the compilation error observed by OP should be triggered if the matching deallocation function ::operator delete cannot be found.

但是,GCC 8.1.0和Clang 6.0.0都使用以下代码(独立于noexcept说明符)引发了编译时错误:

However, both GCC 8.1.0 and Clang 6.0.0 throw a compile time error with the following code (independently of noexcept specifier):

class X {
   public:
      X() /* noexcept */ { }    
   private:
      static void operator delete(void*) { }
};

int main() { 
    X* x = new X{}; 
}

但是MSVC 19.00可以很好地编译!

But MSVC 19.00 compiles it fine!

这篇关于尽管构造函数被标记为noexcept,但GCC仍会产生隐藏的delete运算符调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆