Sign in to follow this  
SymLinked

Unity MSVC static lib linking culls some code?

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this