Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

level10boy

More Meyers Singleton woes with VC++

This topic is 5901 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, I''ve bit the bullet and made the destructor public but now I have a new problem. Everything is fine until I hit Release build with maximum speed optimizations turned on. The constructor for my Meyers singletons gets called twice, which I find hard to believe as it doesn''t happen with any other build type. The object basically gets constructed twice. I must say I cannot see why this is hapenning and am totally mistified. Any advice or answers will be much appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Hmmm... Make sure you do NOT inline the getInstance()
method or "funny things could happen". Remember, in debug
build, inlining is turned OFF .



Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
Thankyou oh so much, I stopped the Instance method from being inlined and it totally solved the problem. Can you explain exactly why this fixed it.

Thanks

Share this post


Link to post
Share on other sites
It''s quite simple actually. When you inline a method,
the actual code is copy & pasted by the compiler to
replace the function call. So if your getInstance() is
copied twice or more, you''ll get many instances of your
"singleton".

In general, it''s a BAD idea to inline methods that
contain static data for exactly that reason.



Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
In case somebody doesn't know what I was talking about in
the previous post, I forgot to mention that the Meyers
Singleton is usually implemented as:


    
// In Singleton.h

class Singleton
{
public:
static Singleton &getInstance(void);
}
// end


// In Singleton.cpp

Singleton &Singleton::getInstance(void)
{
static Singleton s_Singleton;
return s_Singleton;
}
// end



[Edit: changed getInstance() to static]



Kami no Itte ga ore ni zettai naru!

[edited by - tangentz on July 29, 2002 10:31:22 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by tangentz
It''s quite simple actually. When you inline a method,
the actual code is copy & pasted by the compiler to
replace the function call. So if your getInstance() is
copied twice or more, you''ll get many instances of your
"singleton".

In general, it''s a BAD idea to inline methods that
contain static data for exactly that reason.



That is close but not quite right. The problem is not with the inline, but static.

Static variables inside inline functions share the same variable throughout the whole program. (section 7.1.4.2)

Static functions ( deprecated now, should be functions in unnamed namespaces) are defined inside each translation unit. Therefore, the static keyword is causing the multiple definition of the function.

Consider this.

inline void Shared()
{
static int shared; // external linkage, whole program share same instance
}

// note: deprecated, use unnamed namespace instead
static void Local()
{
static int local; // internal linkage, every cpp file have an instance of this
}


For a inlined static class member function, the linkage should be external. Unless you are using an very old compiler which is confused by the inline and static but I don''t think VC++ 6 is one of them. Perhaps level10boy who like to paste his test case.

Ps. Your meyer singleton is wrong. I believe you need to declare getInstance as a static member function, unless you are showing a different variant.

Share this post


Link to post
Share on other sites
static works differently on member functions than on global functions, and there aren''t any global functions here. I would have thought the compiler would have been smart enough to realise that the function had static variables and would refuse to inline it though...

If I had my way, I''d have all of you shot!


codeka.com - Just click it.

Share this post


Link to post
Share on other sites
quote:
Original post by Void
That is close but not quite right. The problem is not with the inline, but static.



Err, but the problem is inline and static.

quote:

Static variables inside inline functions share the same variable throughout the whole program. (section 7.1.4.2)



True, in theory. But some "popular" compilers don''t conform
to this. Scott Meyers talks about it in Effective C++ and
More Effective C++. I know this because I experienced the
exact same thing. We''re talking VC++ here...

quote:

Consider this.
inline void Shared()
{
static int shared; // external linkage, whole program share same instance
}



Not if the compiler is "faulty". Shared() is copied as
many times as it is inlined, causing multiple instances
of the static variables to be present. See MEC++. The only
way to be sure is to make Shared() non-inline.

quote:

// note: deprecated, use unnamed namespace instead
static void Local()
{
static int local; // internal linkage, every cpp file have an instance of this
}



Sorry, but this is wrong. A static function exists ONLY
in the translation unit (CPP) where it is compiled in. You
can''t even extern and use it, because it has internal linkage.
Only ONE instance of this is present.

quote:

For a inlined static class member function, the linkage should be external. Unless you are using an very old compiler which is confused by the inline and static but I don''t think VC++ 6 is one of them. Perhaps level10boy who like to paste his test case.



Unfortunately, VC++ 6 is one of them.



Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
quote:
Original post by Dean Harding
static works differently on member functions than on global functions, and there aren''t any global functions here. I would have thought the compiler would have been smart enough to realise that the function had static variables and would refuse to inline it though...



VC++ 6 (don''t know about 7) would gladly inline functions with
static variables (BAD idea!).





Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
quote:
Original post by tangentz
VC++ 6 (don''t know about 7) would gladly inline functions with
static variables (BAD idea!).



Wow, I never knew that I''ll try it out on VS.NET later on and see if it''s fixed...

If I had my way, I''d have all of you shot!


codeka.com - Just click it.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!