Sign in to follow this  
krum

how to get linker to link in unreferenced static data?

Recommended Posts

I've got a piece of code that looks like this:
#include <iostream>
#include "mylib.h"

class MyClass
	: public IMyClass
{
public:
	virtual void Hello()
	{
		std::wcout << L"Hello, world!" << std::endl;
	}
};

factory<MyClass> myFactory();

When I link, the constructor at the bottom of this source file is never called. Amazingly, if I build it into a DLL, it does link in and is called, but if this code is compiled into a static library or directly into an exe project, it's discarded. I was wondering if anybody knew what the option was to keep this from going away? I tried the "Keep Unreferenced Data (/opt:noref)" and that doesn't work. I have a more complete working example of the problem if you think this is a challenge for you. :D

Share this post


Link to post
Share on other sites
I'm not entirely sure what you're expecting to happen and what is happening. It sounds like you're expecting the line:

factory<MyClass> myFactory();

to instantiate a global instance of factory<MyClass> called myFactory. It won't. It declares a global function which takes no arguments and returns a factory<MyClass>. Remove the parentheses to define a global variable instead.

Σnigma

Share this post


Link to post
Share on other sites
Quote:
Original post by Enigma
I'm not entirely sure what you're expecting to happen and what is happening. It sounds like you're expecting the line:

factory<MyClass> myFactory();

to instantiate a global instance of factory<MyClass> called myFactory. It won't. It declares a global function which takes no arguments and returns a factory<MyClass>. Remove the parentheses to define a global variable instead.

Σnigma


QFT.

Also, if it's *not* referenced, why do you *need* it to be linked in?

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by Enigma
I'm not entirely sure what you're expecting to happen and what is happening. It sounds like you're expecting the line:

factory<MyClass> myFactory();

to instantiate a global instance of factory<MyClass> called myFactory. It won't. It declares a global function which takes no arguments and returns a factory<MyClass>. Remove the parentheses to define a global variable instead.

Σnigma


QFT


I didn't know you could put function prototypes inside functions. Amazing. I've just tried it and it works but it still seems to put the function in the global namespace:


void f()
{
void z();
}

void g()
{
z();
}

void z()
{
printf("hello from z\n");
}

int main(int,const char **av)
{
g(); return 0;
}



Compiled, ran and printed z's message on digital mars compiler. What is the point in that?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
This is a common problem with class factories.
When linking with a static LIBRARY, unreferenced globals will be stripped from the libraries by the linker. They will not be stripped however from a DLL or EXE, only from external libraries.

A common way to get around this problem is to have some include file which you include in your main .EXE project that directly references these static variables. If you are using visual studio 2005 there is a special undocumented pragma that you can use to directly force inclusion of static variables using the mangled name,

__pragma comment(linker,"/include:?variable_name@")

Naturally replacing variable_name with the name of your static global.

DOneAndOnlyMe@hotmail.com

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
This is a common problem with class factories.
When linking with a static LIBRARY, unreferenced globals will be stripped from the libraries by the linker. They will not be stripped however from a DLL or EXE, only from external libraries.

A common way to get around this problem is to have some include file which you include in your main .EXE project that directly references these static variables. If you are using visual studio 2005 there is a special undocumented pragma that you can use to directly force inclusion of static variables using the mangled name,

__pragma comment(linker,"/include:?variable_name@")

Naturally replacing variable_name with the name of your static global.

DOneAndOnlyMe@hotmail.com


AFAIK an unreferenced global class object will not be stripped by any linker since it is implicitly referenced by its own constructor call. If you remove the parentheses from your original code as already suggested, it should be fine.

I quite commonly use "sentry" classes that are statically declared in units in anonymous namespaces and not referenced anywhere except by their own constructor/destructors and have never had a 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