c++ destructor calls a delete operator?
Asked Answered
B

2

14

Why does my MSVC12 compiler not like this?

#include <new>

class thing
{
public:
    thing() {}
    ~thing() {}
    static void operator delete(void* ptr) = delete;
};

int main()
{
    int g;
    void* p = &g;
    thing* t1 = new(p) thing();
    t1->~thing();

    return 0;
}

The error I get is oddly on the closing brace of main():

Error 2 error C2280: 'void thing::operator delete(void *)' : attempting to reference a deleted function

If I comment out the explicit destructor call, the error goes away, implying that the explicit destructor call is trying to call operator delete(void*). This does not make intuitive sense. As you can probably see from the code here, I've already managed my own memory, and I don't want anyone to call delete on thing ever.

Baleen answered 23/3, 2016 at 23:0 Comment(7)
It compiles and works in gcc5, as it should. What happens if you compile in release mode?Scythia
cpp.sh/3mqd - gcc works finePearse
Release build has the same error. Seems this is a compiler bug?Baleen
Same error for MSVC2015 !Cherilyncherilynn
Well, at least it's not really calling thing::operator delete. removing = delete and inserting a printf() in there doesn't execute.Baleen
Check sizeof(thing) <= sizeof g , the new may write out of bounds otherwise. Also, can you reproduce the bug using void *p = ::operator new(sizeof(thing)); , instead of using an int variable?Shupe
I would guess that it has to do with the deleting destructor, one of two helper methods MSVC silently adds to classes with non-trivial destructors to aid with calls to operator delete() (by acting as a wrapper for the delete and destructor calls). For some reason, it would appear that in this particular situation, placement new makes it try to use that method instead of using the destructor directly. I may be wrong, but that's the only logical connection I can think of between operator delete() and ~T() in MSVC, when the object isn't explicitly deleted.Deutero
P
5

This is definitely a bug since by simply replacing the virtual call to the destructor with a nonvirtual one: t1->thing::~thing() it works. But obviously in this case there is no inheritance involved and therefore no difference between the two forms.

You can try and submit the bug through the Microsoft Connect site for VS

Plassey answered 24/3, 2016 at 0:13 Comment(2)
The destructor is not virtualShupe
It's not, but a call that uses the explicit method name is called a nonvirtual call.Plassey
B
3

The consensus in this thread is that this is a compiler bug unique to MSVC++. I have reported this to Microsoft here:

https://connect.microsoft.com/VisualStudio/Feedback/Details/2511044

UPDATE: MS reports that the issue is resolved and will be available in the next VS update.

Baleen answered 24/3, 2016 at 21:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.