我如何允许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。

+0

什么是错误讯息? – user463035818

+1

通过什么样的逻辑你想让单身从自己的构造函数访问自己? – VTT

+0

将对Stuff :: Stuff的构造函数的getTwo()的访问移至某个函数init。构造实例后,使用getInstance中的call_once调用此函数,并将getTwo的值传递给它。 –

/Zc:threadSafeInit- 

一般的“一致性”页MSDN: Conformance,详细介绍其新的功能,您可以禁用。

我需要sizeDealloc的代码,其中我的新编译器正在创建一个大小为一个库的新运算符,该运算符打破了较旧的编译期望值。

由于这是一个编译标志,至少有一些代码将在您的控制之下,您应该能够解开野兽。

构造函数Stuff::Stuff正在对未完成构造的对象调用函数。

这将创建“未定义的行为”。如果值“2”没有设置,直到构造函数结束(例如)。

可能Singleton需要分成2个,一个提供早期的静态数据(例如2个)。

第二个发送持有的对象的东西。东西只会依靠第一个,这会打破僵局。

另外,第二构造函数来Stuff它告诉它要使用哪个对象,并从Singleton::Singleton

MSDN文章被称为禁用“魔法静” MSDN : disable threadsafe static initialization