2

I am trying to work around the fact that linker drops the registration in my code. See this answer for details.

The problem I have with that answer is that the --whole-archive option seems like an overkill for just 1 function call. I would like to avoid huge code bloat that I assume it causes. I found

attribute((used))

, but that works on compile, not link level.

So I wonder if there is a specific way to tell the linker to not drop specific function call, instead of changing link options for entire program.

for clarification this is my code:

bool dummy = (Register(), false); // Register is never called because linker dropped entire static library
Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • 1
    What do you mean by "drops the registration"? Also, details of linker behavior are implementation-specific, so which implementation are you using? GCC, maybe? – John Bollinger Apr 25 '19 at 18:39
  • @JohnBollinger linked answer provides the longer explanation... in short I have bool dummy = (Register("Something1"), false); and linker drops the entire library so the Register() is never called – NoSenseEtAl Apr 25 '19 at 18:52
  • It's not clear that the situation you describe is analogous to the answer you reference. It is especially not clear that the linker is responsible for the (mis)behavior involved in your case, and, moreover, the best choice of solution may well depend on context. So please present a [mcve] that demonstrates the issue. – John Bollinger Apr 25 '19 at 19:02

2 Answers2

4

So I wonder if there is a specific way to tell the linker to not drop specific function call, instead of changing link options for entire program.

Your objective is actually to tell the linker not to drop the definition of an unreferenced variable (dummy) in whose initialiser there is a function call that you wish to ensure is executed by your program.

__attribute__(used) is an attribute of functions, but not of variables, and its effect is to force the compiler to compile the function definition, even if the function is static and appears unreferenced in the translation unit. In your case:

bool dummy = (Register(), false);

it cannot appear to the compiler that Register is unreferenced - it is called - so __attribute__(used) will be redundant even if the definition of Register() is in the same translation unit and is static. But whether or not the definition of Register() is compiled in this translation unit or some other, this call to Register() will not be linked or executed in the program if this definition of dummy is not linked.

I assume you do not want to write a custom linker script, or to modify the source code so that dummy is referenced.

In that case you need to instruct the linker to postulate an undefined reference to dummy, by passing --undefined=dummy in its options. This will force it to search libraries for a definition of dummy, and to link archive members (and/or shared libraries) exactly as if there actually was an undefined reference to dummy in the first file that is linked. No redundant code will be linked, as is probable with --whole-archive.

You can pass --undefined=<symbol> to the linker for as many values of <symbol> as you like. To pass it through gcc/g++, use -Wl,--undefined=<symbol>.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
1

Put it in its own section and in the linker script:

KEEP(sectionname)

edit

That line of code might be reduced to zeroing one register or variable

0___________
  • 60,014
  • 4
  • 34
  • 74