473,581 Members | 3,183 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

std::atexit

I am attempting to write a "Phoenix Singleton" using the book "Modern C++
Design" by Alexandrescu
I do not understand his use of...

#ifndef ATEXIT_FIXED
std::atexit(Kil l);
#endif

....in the source below. I understand the problem, but not how a preprocessor
directive will fix it. He says the standard is unclear about the situation
where one call to register with std::atexit is the result of is made as an
effect of another std::atexit registration. Can anyone be more specific on
how to fix the problem?

Source (forgive the indenting problems as a result of editor
incompatibiliti es):
// .h file
#ifndef SINGLETON_PHOEN IX
#define SINGLETON_PHOEN IX
#include "BaseException. h"
namespace cpisz_common_li b
{
//----------------------------------------------------------------------------------------------------------------------
/**
* Singleton_Pheon ix
*
* A singleton pattern that guarentees an instance will always be available.
*
*/
class Singleton_Phoen ix
{
public:
/**
* Retreives a reference to this singleton
*/
static Singleton_Phoen ix & GetInstance();
private:
static void Create();
static void Kill();
static void OnDeadReference ();
Singleton_Phoen ix();
Singleton_Phoen ix(const Singleton_Phoen ix &);
virtual ~Singleton_Phoe nix();
Singleton_Phoen ix & operator = (const Singleton_Phoen ix &);
static Singleton_Phoen ix * m_instance; // Pointer to the instance of this
object
static bool m_destroyed; // Flag that indicates the instance has been
destroyed
};
} // namespace cpisz_common_li b
#endif

// .cpp file
#include "Singleton_Phoe nix.h"
#include <cstdlib>
namespace cpisz_common_li b
{
//----------------------------------------------------------------------------------------------------------------------
Singleton_Phoen ix * Singleton_Phoen ix::m_instance = 0;
bool Singleton_Phoen ix::m_destroyed = false;
//----------------------------------------------------------------------------------------------------------------------
Singleton_Phoen ix & Singleton_Phoen ix::GetInstance ()
{
// Check if the object is instantiated
if( !m_instance )
{
// Check for dead reference
if( m_destroyed )
{
// Create a new instance, replacing the old destroyed instance
OnDeadReference ();
}
else
{
// Create the first instance
Create();
}
}
return *m_instance;
}
//----------------------------------------------------------------------------------------------------------------------
void Singleton_Phoen ix::Create()
{
static Singleton_Phoen ix instance;
m_instance = &instance;
}
//----------------------------------------------------------------------------------------------------------------------
void Singleton_Phoen ix::Kill()
{
// Set the instance pointer to NULL and destroyed flag to true;
m_instance->~Singleton_Pho enix();
}
//----------------------------------------------------------------------------------------------------------------------
void Singleton_Phoen ix::OnDeadRefer ence()
{
// Get the shell of the old reference to the instance
Create();
// Create a new instance at that same address
// Using the "placement new operator"
new(m_instance) Singleton_Phoen ix;
// Queue this new objects destruction
#ifndef ATEXIT_FIXED
std::atexit(Kil l);
#endif
// Reset the destoryed flag
m_destroyed = false;
}
//----------------------------------------------------------------------------------------------------------------------
Singleton_Phoen ix::~Singleton_ Phoenix()
{
m_instance = 0;
m_destroyed = true;
}
} // namespace cpisz_common_li b
Jan 2 '08 #1
2 4749
On Jan 2, 6:19 am, "Christophe r Pisz" <some...@somewh ere.netwrote:
I am attempting to write a "Phoenix Singleton" using the book
"Modern C++ Design" by Alexandrescu I do not understand his
use of...
#ifndef ATEXIT_FIXED
std::atexit(Kil l);
#endif
...in the source below. I understand the problem, but not how
a preprocessor directive will fix it. He says the standard is
unclear about the situation where one call to register with
std::atexit is the result of is made as an effect of another
std::atexit registration.
C99 is not unclear about this (although I seem to remember it
being undefined behavior in C90, and thus in C++98).
Can anyone be more specific on how to fix the problem?
Which problem? The code you posted has several different cases
of undefined behavior. All the #ifndef does is cause atexit not
to be called if ATEXIT_FIXED is defined.

I've not studied it in detail, but even after a quick glance, it
is apparent that if Kill() is ever called (and it will be called
if atexit is called), the destructor is called twice for the
same object. This is undefined behavior, and in a non-trivial
class, will almost certainly get you into trouble. So you
almost certainly have to defined ATEXIT_FIXED for the code to
work.

The obvious way to achieve the supposed goal (that an instance
will always be available) is to create the instance with new,
and never destruct it.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 2 '08 #2
On Jan 2, 6:02 am, James Kanze <james.ka...@gm ail.comwrote:
On Jan 2, 6:19 am, "Christophe r Pisz" <some...@somewh ere.netwrote:
[snip]
He says the standard is
unclear about the situation where one call to register with
std::atexit is the result of is made as an effect of another
std::atexit registration.

C99 is not unclear about this (although I seem to remember it
being undefined behavior in C90, and thus in C++98).
What does C99 say about it?
Can anyone be more specific on how to fix the problem?

Which problem? The code you posted has several different cases
of undefined behavior. All the #ifndef does is cause atexit not
to be called if ATEXIT_FIXED is defined.
That is what I suspected. If that is the case I don't see any reason
to put the preprocessor directive in there at all. I should always
execute that block.

I've not studied it in detail, but even after a quick glance, it
is apparent that if Kill() is ever called (and it will be called
if atexit is called), the destructor is called twice for the
same object. This is undefined behavior, and in a non-trivial
class, will almost certainly get you into trouble. So you
almost certainly have to defined ATEXIT_FIXED for the code to
work.
So, the code will not have undefined behavior if I remove the
preprocessor directive in that case? I do not see the other cases you
speak of even after examining the code in detail. The only problem I
can forsee is what happens at application exit when a registration
using std::atexit() is made as a result of another registration using
atexit(), which is the behavior my post is asking about. Anyone see
other cases of undefined behavior? Anyone have a definition of the
behavior mentioned?

The obvious way to achieve the supposed goal (that an instance
will always be available) is to create the instance with new,
and never destruct it.
I am unclear about this suggestion. If I new something and do not
delete it, is that not a memory and possibly a resource leak? What
will happen in the case that one of these singletons is dependent on
another at the time of application exit?

I am getting the feeling that what you are telling me is that this
book is out of date and there may be a better solution available. If
so, does anyone have a link? I have googled and found several
singleton implementations , but none of which seem to address the flaws
that this one is attempting to address.

I really want to try to avoid the authors proposal of implementing a
"dependency manager" and global "setlongevity(i nt)" methods. It seems
overly complex to me.
Jan 2 '08 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
4836
by: Siemel Naran | last post by:
Hi. I posted this question to comp.lang.c++, but am rephrasing it a bit from what I learned and posting to comp.lang.c++.moderated for more insight. So how do I solve my problem? I want it so that when the user presses Ctrl-C or eds the task from task manager (or the kill command in UNIX) then the system should shutdown gracefully. This...
8
2826
by: JKop | last post by:
Let's say that when your program ends (no matter how) that you want a certain block of code to be executed at the end. Here's the code: std::cout << "The program will now end.\n"; std::system("PAUSE"); I've looked up "exit", "atexit" and "abort". Up until this point I simply would've done:
11
912
by: Jonan | last post by:
Hello, For several reasons I want to replace the built-in memory management with some custom built. The mem management itlsef is not subject to my question - it's ok to the point that I have nice and working allocation deallocation routines. However, I don't want to loose the nice extras of new operator, like - constructor calling,...
5
1403
by: John Ratliff | last post by:
For code that was part of the C library, being used in C++, should you always prefix std:: Specific examples: std::fopen std::fclose std::atexit Should I include
11
3155
by: tomgee | last post by:
I saw it many times, // T.h: class T { public: static T* instance(); private: T() {}
12
1882
by: keepyourstupidspam | last post by:
Hi, I am writing a windows service. The code runs fine when I start the service when my machine is running but it fails to start automatically when the machine reboots. The code bombs out when it reaches code that tries to access a singleton class. This is the code.
7
6630
by: Adrian | last post by:
Hi, I have a large unmanaged static C++ library which I've wrapped using a small C++/CLR DLL. This is called from a C# client application. The static library has a singleton, however it appears that it is being instantiated twice. The first instantiation is down to me calling singleton.instance() in the C++/CLR DLL, the second...
0
1218
by: Andreas Schmitt | last post by:
I am trying to get the PhoenixSingleton pattern example found in "Modern C++ Design" to run. I am using the Singleton in a DLL. I don't deliver any references of the Singleton to outside-DLL callers so that's not my problem. The singleton works perfectly, the only problem is.. after reviving the singleton, it doesn't get destroyed, meaning...
0
7788
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8299
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7890
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
1
5667
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5357
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3799
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3813
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1398
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1127
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.