Search code examples
c++visual-c++gcc5.2

Linker error while building with MSVC 2015 (other CC are OK)


Here is the MCVE:

#include <iostream>
#include <string>

using namespace std;

class Obj {
public:
    Obj() { cout << "Obj()" << endl; }
    ~Obj() { cout << "~Obj()" << endl; }
    void* operator new(size_t sz){
        return ::operator new(sz);
    }
    void operator delete(void* p) {
        ::operator delete(p);
    }
private:
    friend class MyClass;
    void* operator new(size_t, void*);
    void operator delete(void*, size_t);
};

class MyClass {
public:
    MyClass() : m_(new Obj) {
        cout << "MyClass()" << endl;
    }
    ~MyClass() {
        cout << "~MyClass()" << endl;
        delete m_;
    }
private:
    const Obj * m_;
};

int main()
{
    cout << "Started" << endl;
    MyClass o;
    cout << "Finished" << endl;
    return 0;
}

Building with MSVC 2015 (14.0):

error LNK2019: unresolved external symbol "private: static void __cdecl Obj::operator delete(void *,unsigned int)" (??3Obj@@CAXPAXI@Z) referenced in function __unwindfunclet$??0MyClass@@QAE@XZ$0

Building with MSVC 2013 (12.0): OK

Building with GCC 5.2: OK

Questions:

Why?

How to fix / work around?

P.S.

Original file in QtScript project.


Solution

  • Taking into account Breaking Changes in Visual C++ 2015 I incline to the follow decision:

    class Obj {
    ...
    private:
        friend class MyClass;
        void* operator new(size_t, void*);
    #if defined(_MSC_VER) && _MSC_VER >= 1900
        enum class Obj_tag : size_t {};
        void operator delete(void*, Obj_tag);
    #else
        void operator delete(void*, size_t);
    #endif
    };
    

    So, the following code

    #ifdef ERROR_TEST
    char buf[1024] = { 0 };
    Obj * o1 = reinterpret_cast<Obj*>(buf);
    new (o1) Obj;
    #endif
    MyClass o2;
    

    is compiled in the same way both with MSVC 2012 and with MSVC 2015. (When ERROR_TEST is defined there is the error C2248: 'Obj::operator new': cannot access private member declared, and when is not - all OK)