how to get linker to link in unreferenced static data?

Started by
5 comments, last by Aardvajk 17 years, 10 months ago
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
Advertisement
Does this work?
extern "C" factory<MyClass>* UnusedGetFactory() {  return &myFactory}


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

This topic is closed to new replies.

Advertisement