使用 MSVC 2015 构建时出现链接器错误(其他 CC 都可以)
Linker error while building with MSVC 2015 (other CC are OK)
这里是 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;
}
使用 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[=11=]
使用 MSVC 2013 (12.0) 构建:正常
使用 GCC 5.2 构建:正常
问题:
为什么?
如何解决/变通?
P.S.
Original file 在 QtScript 项目中。
考虑到Breaking Changes in Visual C++ 2015我倾向于以下决定:
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
};
所以,下面的代码
#ifdef ERROR_TEST
char buf[1024] = { 0 };
Obj * o1 = reinterpret_cast<Obj*>(buf);
new (o1) Obj;
#endif
MyClass o2;
在 MSVC 2012 和 MSVC 2015 中的编译方式相同。(当定义 ERROR_TEST
时,有 error C2248: 'Obj::operator new': cannot access private member declared
,如果没有 - 一切正常)
这里是 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;
}
使用 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[=11=]
使用 MSVC 2013 (12.0) 构建:正常
使用 GCC 5.2 构建:正常
问题:
为什么?
如何解决/变通?
P.S.
Original file 在 QtScript 项目中。
考虑到Breaking Changes in Visual C++ 2015我倾向于以下决定:
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
};
所以,下面的代码
#ifdef ERROR_TEST
char buf[1024] = { 0 };
Obj * o1 = reinterpret_cast<Obj*>(buf);
new (o1) Obj;
#endif
MyClass o2;
在 MSVC 2012 和 MSVC 2015 中的编译方式相同。(当定义 ERROR_TEST
时,有 error C2248: 'Obj::operator new': cannot access private member declared
,如果没有 - 一切正常)