Jump to content
  • Advertisement
Sign in to follow this  
SymLinked

Unity MSVC static lib linking culls some code?

This topic is 2803 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 use macros in quite a few places for classes that need to be created based on their name or ID. It's useful for scripting, serializing and when networking our game. It's basically a dummy struct with a constructor that is initialized before main.

Quote:

#define IMPLEMENT_OBJECT(name) struct name##Creator { name##Creator () { ObjectManager::addObject (#name, new name); } }; name##Creator name##CreatorInstance;


(Had to modify the source above to a quote or it would screw up the formatting of the page)

Ugly perhaps, but these work great in .cpp files in all cases so far, but today I decided to branch them out into their own lib because I use them in so many projects.

So it seems that if I put one in a .cpp file that contains a class that is never referenced anywhere else, it won't get called at all even though it's actually referenced in the macro itself. This happens only when in the library, and not in the projects themselves so it's not very consistent.

Putting the macro "call" in a .h file that is included didn't help. I have to actually reference the class in those files for the dummy initializer to run.

I know about the compiler option, but is there a pragma or reference trick that I can use to make the library .cpp file compiled and used in all cases like it does in my project?

[EDIT]
It's the same issue mentioned here:
Link

And there are a few mentioned "solutions" though the last one doesn't work and it's still unreferenced. The pragma also didn't work, it finds the symbol but it's not referencing it (since the code still isn't executed).

This is how I tested it:
Quote:

struct Test
{
Test ()
{
MessageBoxA (NULL, "Test", "It works!", MB_OK);
}
};
Test TestInstance;

#pragma comment(linker,"/include:TestInstance")

[/EDIT]

Global Compiler/Linker options have no effect.

Thank you for any suggestions!

[Edited by - SymLinked on November 12, 2010 2:09:18 AM]

Share this post


Link to post
Share on other sites
Advertisement
Ah, this wonderful bug. I don't think there is any real solution, but there is a workaround:

1) Add a:
void doAbsolutelyNothing() { }
function in the same source file as the instances of the objects you are creating. If you have multiple source files with instances, you'll need multiple functions with different names.

2) Call this:
doAbsolutelyNothing();
function from some other part of your source, such as in initialization code, or code which is only called once.

The VC linker doesn't include object files in the final .exe with no external references as it assumes they're never used (it's apparently not smart enough to notice that object variables are simply instanced in that compilation unit). By adding an external reference, you force the inclusion of that object in the linker.

You could optionally make a variable reference to your TestInstance from some other part of your source which would work just as well, but since you're generating these names with macros, that seems like it would be much more difficult for you.

Share this post


Link to post
Share on other sites
It's not a bug. This is related to dynamic initializers.

Gory details for the GNU linker, but the idea seems to be the same for the Visual C++ linker in my experience.

Have you tried passing /OPT:NOREF to the linker? (Though beware of dragging in lots of other bloat).

Share this post


Link to post
Share on other sites
Quote:
Original post by SymLinked]Ugly perhaps, but these work great in .cpp files in all cases so fars ...

That is not far from my description of a hack and sometimes when you play with fire you do get burnt.

You are relying on the static initialisation of an object which may not be used, to access global (probably) state in ObjectManager::addObject.

Quote:
Original post by SymLinkedThank you for any suggestions!

You may not like it but fix the source of the problem not the current problem.

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!