I tricked the linker :(

Started by
20 comments, last by joanusdmentia 18 years ago
Quote:Original post by AndyTX
I've had similar problems before. The simple solution is to turn off the linker option that rips out unreferenced code ;)
Haha, I do like to keep my link times relatively short :)

Quote:Another solution that may work for you is to put the static variable declaraion in the header file. This isn't ideal, but it helps the linker to realize specifically that you want a template instantiation of that type, and not to rip it out (as there's technically a global variable floating around now... put it in a namespace or something to make it prettier).

Unfortunately, I'll have to wait till tommorow to test out this theory, but I can't imagine it working because the header file isn't included from anywhere. How would it make any difference?

Advertisement
I suspect that it's the static keyword confusing things. static in this context says 'do no make this symbol visible outside of this translation unit', so the generated .obj file will have no symbols in it and thus not included by the linker. Try removing the static keyword and placing the declaration inside an anonymous namespace instead.

// .cpp filenamespace{    FactoryInstaller<DerivedFactory> factory;}

"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Can you try this?

int f()
{
FactoryInstaller<DerivedFactory>* factory = new FactoryInstaller<DerivedFactory>;
return rand();// you return anything you want
}

static int i = f();
You can just simply, and evil-ly, add the .obj file to your project like it was a C or C++ file ;)
Quote:Original post by Anonymous Poster
You can just simply, and evil-ly, add the .obj file to your project like it was a C or C++ file ;)


Not only is that an incredibly bad idea, it won't even work.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Quote:Original post by joanusdmentia
I suspect that it's the static keyword confusing things. static in this context says 'do no make this symbol visible outside of this translation unit', so the generated .obj file will have no symbols in it and thus not included by the linker. Try removing the static keyword and placing the declaration inside an anonymous namespace instead.

*** Source Snippet Removed ***


Putting an object in an unnamed namespace means 'do no make this symbol visible outside of this translation unit'. In fact, using 'static' like that has been deprecated in favor of unnamed namespaces. So, that really doesn't change things [wink]
Quote:Original post by RDragon1
Quote:Original post by joanusdmentia
I suspect that it's the static keyword confusing things. static in this context says 'do no make this symbol visible outside of this translation unit', so the generated .obj file will have no symbols in it and thus not included by the linker. Try removing the static keyword and placing the declaration inside an anonymous namespace instead.

*** Source Snippet Removed ***


Putting an object in an unnamed namespace means 'do no make this symbol visible outside of this translation unit'


Wrong. Take a look at the generated .obj file and the symbol will still be there, prefixed with a randomly generated string (the anonymous namespace) to make it impossible (well, nearly impossible) to reference externally but it's still there. Using the static keyword the symbol simply doesn't exist in the .obj file.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Well, okay, that might be correct, but it's a very subtle difference, and it has the same effect - it can't be referenced from outside of the translation unit. And it doesn't help force the linker into including the static object when there is no other reference to the translation unit.

How could the symbol not exist? If you have some function that uses the object, does it exist then? Maybe you're just seeing the artifacts of the optimization...
Quote:How could the symbol not exist? If you have some function that uses the object, does it exist then? Maybe you're just seeing the artifacts of the optimization...


The symbol doesn't exist *external* to the translation unit. When compiling, whenever the symbol is seen in that translation unit it is replaced with an appropriate (relocatable) memory address that references into the .data section. However no symbol name is placed in the .obj file, therefore no other translation unit can reference that symbol.

Quote:but it's a very subtle difference, and it has the same effect

Actually, it's a very significant difference. If the only symbol he has in that translation unit is the static FactoryInstaller instance then the .obj file will appear empty to the linker (containing only a block of data that can never be referenced). When using an anonymous namespace the linker will still see that there is a symbol within the .obj file, the linker doesn't care that the symbol has a randomly generated prefix so can't be referenced by another translation unit, there's still a symbol.

Now, I'm not saying this *will* work, but it's worth a shot (and besides, IIRC the standard recommends using an anonymous namespace instead of the static keyword).
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
The thing that I want to know, though, is what's going on in the FactoryInstaller<> constructor.

If it references any code in another file/translation unit, the linker should know about it and link it in, right?
daerid@gmail.com

This topic is closed to new replies.

Advertisement