1

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

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?

Jodocus
  • 7,493
  • 1
  • 29
  • 45
RedSoft
  • 373
  • 2
  • 15
  • 3
    Provide [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Daniel Langr Jun 28 '18 at 12:40
  • 1
    I fail to see how are exceptions involved. This is a compile time error, Exceptions are fully run-time feature and they don't call any `delete` that is not in a destructor of a class. – Yksisarvinen Jun 28 '18 at 12:43
  • "constractor"?? – BЈовић Jun 28 '18 at 12:46
  • 1
    @Yksisarvinen If the constructor throws, `delete` must be invoked by the compiler to free the possibly allocated memory. – Daniel Langr Jun 28 '18 at 12:50
  • 1
    @DanielLangr Thanks, I didn't know that. Shouldn't `noexcept` prevent that behaviour? Since constructor can't throw and `std::terminate` will be called... – Yksisarvinen Jun 28 '18 at 13:02
  • 1
    @Yksisarvinen I can't find anything related to `noexcept` in this situation in the Standard. See my answer for related paragraphs. – Daniel Langr Jun 28 '18 at 13:12

1 Answers1

2

From expr.new:

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 ]

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.

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{}; 
}

But MSVC 19.00 compiles it fine!

Daniel Langr
  • 22,196
  • 3
  • 50
  • 93
  • @BoPersson I asked a new question about this issue since I believe it deserves one. Please, discuss there: https://stackoverflow.com/q/51084262/580083 – Daniel Langr Jun 28 '18 at 13:33
  • 1
    I was a bit too quick with my comment. The `noexcept` still affects the result. – Bo Persson Jun 28 '18 at 13:34