Jump to content
  • Advertisement
Sign in to follow this  
paic

Object factory and objects registration ...

This topic is 3939 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

Hi, I've got a little problem with object factories and more specifically the registration of creation functions. This is how I usually do it :
// for example, in Mesh.cpp :
#include "Mesh.h"
#include "NodeFactory.h"

namespace
{
    Object * CreateMesh(void)
    {
        return(new Mesh());
    }

    const bool registered = NodeFactory::Instance()->Register("Mesh", &CreateMesh);
}

class Mesh
{
    // ....
};
I found this method in "Modern C++ Design" by Andrei Alexandrescu, and until recently, it worked perfectly. But now, I'm compiling my engine as a static library, and it doesn't work anymore. When I set a breakpoint in the Register method of the NodeFactory, it is never reached ... Why is that ? And is there a way to solve this problem ?? Thx in advance.

Share this post


Link to post
Share on other sites
Advertisement
Objects with static storage duration are only guaranteed to be initialized if they are used. Since nothing ever uses the registered variable, it's not actually guaranteed to be initialized, so your program has been depending on non-guaranteed behavior. In this case, what's probably happening is that the linker is seeing that nothing in your application that uses the static library ever uses the registered variable, it doesn't bother adding it to your application.

Bottom line, self-registration tricks like this are extremely fragile. Consider using explicit registration techniques instead.

Share this post


Link to post
Share on other sites
I think you ran into the same problem I had a while ago. It seems like the compiler is too aggressive removing unused code.
It probably sees that registered is never used and figures it can just leave out the call to Register().
I ended up creating a static array that contains all CreateXXX() function pointers that is used by the factory.

Share this post


Link to post
Share on other sites
Ok, thanks for the reply. What I still don't understand is I always used this method, with the same compiler, and almost the same source code (I just changed a few things to seperate the engine from the rest of the code and compile it as a .lib) and it's the first time I have this problem.

And I also thought that I could trust a well know book ...

Anyway, the advantage of this method is that the object factory doesn't have to #include all the objects headers, or something like this ... is there any other method that would have the same benefit ?

Share this post


Link to post
Share on other sites
I think you should keep this technic. We're using it in almost the same way on our multiplatform engine (DS, PSP, Wii, Win32) and are very pleased with it.
What we've done is simply studied each compilers we use and found tricks to not strip dead code we really needed.

Share this post


Link to post
Share on other sites
Quote:
Original post by paic
... (I just changed a few things to seperate the engine from the rest of the code and compile it as a .lib)...

That's because what SiCrane described only happens for static libraries, and not for dll's or executables (at least if you're using visual studio).

Share this post


Link to post
Share on other sites
Koen : thanks, I missed the part about static libraries in SirCrane's answer :)
skalco6 : I'd like to, but I don't really know how to make it work in my case ... maybe use registered somewhere in the code ?

Share this post


Link to post
Share on other sites
Silly hacky idea: have a 'numRegistered' global which you increment in Register(), and maybe that will stop the compiler from optimising that call away? You may need to add a function that queries that value to stop the compiler optimising that away too. ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by paic
Anyway, the advantage of this method is that the object factory doesn't have to #include all the objects headers, or something like this ...

You're not really sure, are you. See, these automatic registration thingies are sexy-sounding, but ultimately they create much more hassle than they solve.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
Silly hacky idea: have a 'numRegistered' global which you increment in Register(), and maybe that will stop the compiler from optimising that call away? You may need to add a function that queries that value to stop the compiler optimising that away too. ;)


That won't help in this situation. To the compiler/linker modifying a numRegistered global would be just the same as registering with the factory: a side effect of an initialization. Side effects of initializations will only occur if the initialization occurs, which is only guaranteed to happen with an object of static storage duration if the object is referenced.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • 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!