簡體   English   中英

如何在VS2017中允許單例構造函數重新進入/傳遞?

[英]How can I allow singleton constructor re-entry/pass-over in VS2017?

我一直在將一些c ++應用程序從Visual Studio 2013移植到Visual Studio 2017.除了我必須解決的大量新警告之外,編譯和鏈接也沒問題。

但是,在運行應用程序時,它在嘗試重新進入單例的構造函數時“停頓”(當連續的函數調用形成一個循環回到構造函數時)。 看來這種行為在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) Shift + F11將退出該方法,程序將在指定的行無限期地等待(從調試器暫停程序時觀察)。


PS

此問題也可能發生在Visual Studio 2015中,因為從接受的答案鏈接的文檔提到了VS2015。

/Zc:threadSafeInit-

一般的“一致性”頁面是MSDN:Conformance ,它詳細說明了您可以禁用的新功能。

我需要sizeDealloc的代碼,我的新編譯器正在為一個庫創建一個大小的新運算符,這打破了舊的編譯期望。

因為這是一個編譯標志,所以至少有一些代碼在你的控制之下,你應該能夠解開這個野獸。

構造函數Stuff::Stuff在一個未完全構造的對象上調用一個函數。

這將創建“未定義的行為”。 如果在構造函數結束之前未設置值“2”(例如)。

可能需要將Singleton分成2個,一個提供早期靜態數據(例如2)。

第二個傳遞持有的物品Stuff。 東西只依靠第一個,這將打破僵局。

或者, Stuff的第二個構造函數告訴它使用哪個對象,並從Singleton::Singleton調用

MSDN文章禁用“Magic Statics” MSDN:禁用線程安全靜態初始化

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM