我如何允许VS2017中的单身构造函数重新进入/移交?
我一直在将Visual Studio 2013中的一些C++应用程序移植到Visual Studio 2017中。除了我必须修复的大量新警告外,编译和链接也没问题。我如何允许VS2017中的单身构造函数重新进入/移交?
但是,当运行该应用程序,它试图重新进入单身的构造函数(当连续的函数调用形成一个循环回构造函数)'停滞'。 VS2013中这种行为似乎没有问题,但在VS2017中不再有效。没有错误消息。
我知道所有与单例相关的坏事,至少应该没有循环。问题不在那里。
有没有办法告诉VS2017编译器,我想拍摄自己的脚,并允许在VS2013中有同样的行为?
我无法访问导致此行为的代码,因为它来自第三方库,这就是为什么我不能'修复它',不幸的是。
这里是一个在VS2013工作的例子,但在VS2017不起作用:
的main.cpp
#include "Singleton.h";
int
main(void)
{
std::cout << "let's do this!" << std::endl;
int two = Singleton::GetReference().getTwo();
std::cout << "ok" << std::endl;
return 0;
}
Singleton.h
#pragma once
class Stuff;
class Singleton
{
public:
static Singleton& GetReference();
int getTwo() { return 2; }
private:
Singleton();
Stuff* stuff;
};
Singleton.cpp
#include "Singleton.h"
#include "Stuff.h"
Singleton&
Singleton::GetReference() {
static Singleton theInstance;
return theInstance;
}
Singleton::Singleton()
{
stuff = new Stuff();
}
Stuff.h
#pragma once
class Stuff
{
public:
Stuff();
private:
int two;
};
Stuff.cpp
#include "Stuff.h"
#include "Singleton.h"
Stuff::Stuff()
{
two = Singleton::GetReference().getTwo();
}
在上面的代码中,当一步一步的调试,我们第一次拿到就行static Singleton theInstance;
如预期的工作,但第二次,一F11将转到文件thread_safe_statics.cpp
,进入方法extern "C" void __cdecl _Init_thread_header(int* const pOnce)
。 A Shift + F11将退出该方法,程序将无限期地等待指定的行(在从调试器暂停程序时观察)。
PS
这个问题可能会出现在Visual Studio 2015年也一样,从公认的答案链接的文档中提到VS2015。
/Zc:threadSafeInit-
一般的“一致性”页MSDN: Conformance,详细介绍其新的功能,您可以禁用。
我需要sizeDealloc的代码,其中我的新编译器正在创建一个大小为一个库的新运算符,该运算符打破了较旧的编译期望值。
由于这是一个编译标志,至少有一些代码将在您的控制之下,您应该能够解开野兽。
构造函数Stuff::Stuff
正在对未完成构造的对象调用函数。
这将创建“未定义的行为”。如果值“2”没有设置,直到构造函数结束(例如)。
可能Singleton需要分成2个,一个提供早期的静态数据(例如2个)。
第二个发送持有的对象的东西。东西只会依靠第一个,这会打破僵局。
另外,第二构造函数来Stuff
它告诉它要使用哪个对象,并从Singleton::Singleton
MSDN文章被称为禁用“魔法静” MSDN : disable threadsafe static initialization
什么是错误讯息? – user463035818
通过什么样的逻辑你想让单身从自己的构造函数访问自己? – VTT
将对Stuff :: Stuff的构造函数的getTwo()的访问移至某个函数init。构造实例后,使用getInstance中的call_once调用此函数,并将getTwo的值传递给它。 –