J'ai porté une application c++ de Visual Studio 2013 à Visual Studio 2017. Mis à part la pléthore de nouveaux avertissements que j'ai dû corriger, la compilation et la liaison se sont bien déroulées.
Cependant, lorsque en cours d'exécution l'application, elle " calait " lorsqu'elle essayait de rentrer dans le constructeur d'un singleton (lorsque les appels de fonction successifs forment une boucle vers le constructeur). Il semble que ce comportement était acceptable dans VS2013, mais n'est plus valable dans VS2017. Il n'y a pas de message d'erreur.
Je suis conscient de toutes les mauvaises choses liées aux singletons, et qu'il ne devrait au moins pas y avoir de boucles. La question n'est pas là.
Existe-t-il un moyen d'indiquer au compilateur VS2017 que je souhaite me tirer une balle dans le pied et autoriser le même comportement que celui qui existait dans VS2013 ?
Je n'ai pas accès au code à l'origine de ce comportement car il provient d'une bibliothèque tierce. C'est pourquoi je ne peux malheureusement pas le "réparer".
Voici un exemple qui fonctionne dans VS2013, mais qui ne fonctionne pas dans 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();
}
Dans le code ci-dessus, lors du débogage pas à pas, la première fois que nous arrivons sur la ligne static Singleton theInstance;
fonctionnera comme prévu, mais la seconde fois, une F11 ira dans le fichier thread_safe_statics.cpp
dans la méthode extern "C" void __cdecl _Init_thread_header(int* const pOnce)
. A Shift+F11 quittera la méthode et le programme attendra indéfiniment à la ligne spécifiée (observé lors de la mise en pause du programme depuis le débogueur).
PS
Ce problème se produit probablement aussi dans Visual Studio 2015, car la documentation liée à la réponse acceptée mentionne VS2015.