Skip to main content
GameDev.net gamedev.net
🔒 Locked

how to get linker to link in unreferenced static data?

Started by krum Jun 12, 2006 at 3:13 PM 5 replies 5.3k views
Original Post
krum
krum
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
NotAYakk
NotAYakk
Does this work?
extern "C" factory<MyClass>* UnusedGetFactory() {  return &myFactory}


Enigma
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 myFactory();

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

Σnigma
Zahlman
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 myFactory();

to instantiate a global instance of factory called myFactory. It won't. It declares a global function which takes no arguments and returns a factory. 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?
Aardvajk
Aardvajk
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 myFactory();

to instantiate a global instance of factory called myFactory. It won't. It declares a global function which takes no arguments and returns a factory. 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?
Aardvajk
Aardvajk
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.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.