2

I'm wondering if the compiler/linker will remove global variables that have been extern'd in a public header? For example:

// public.h
struct func_ptrs {
   void (*foo)(void);
   void (*bar)(int);
};

extern const struct func_ptrs DEFAULT_FUNCS;

and:

// private.c
#include "public.h"

void def_foo(void) { ... }
void def_bar(int a) { ... }

const struct func_ptrs DEFAULT_FUNCS = { .foo = def_foo, .bar = def_bar };

Are there any specific linker flags that will allow for this variable (and the two functions) to be stripped from the resulting binary?

Assume GCC and MSVC as the two target compilers.

MarkP
  • 4,168
  • 10
  • 43
  • 84
  • 1
    Take a look here: http://stackoverflow.com/questions/6687630/how-to-remove-unused-c-c-symbols-with-gcc-and-ld – nsilent22 Jan 20 '16 at 21:50

1 Answers1

0

DEFAULT_FUNCS:

Since the symbol DEFAULT_FUNCS - due to its scope and modifiers - is subject to being exported to the symbol table of the binary for (dynamic) linking, it cannot be stripped. In other words: The linker (ld) cannot determine if the symbols will be used or not.

Functions def_foo & def_bar

Furthermore, there are no functions at all which could be stripped, since you only declared them. Indeed, linking of this binary would fail, since def_foo and def_bar are undefined symbols.

One more thing: Correct would be:

const struct func_ptrs DEFAULT_FUNCS = ...

without the asterisk, since you initialize a struct, not a pointer.

Ctx
  • 18,090
  • 24
  • 36
  • 51
  • I updated the original post to assume the functions were implemented. In any case, would `-flto` help in stripping during linking? – MarkP Jan 21 '16 at 15:30
  • It depends. If the symbols are in the dynamic symbol table (option -rdynamic), the link time optimizer cannot remove it, since it doesn't know if it will be linked at runtime. With standard options, it can detect that the symbol DEFAULT_FUNCS isn't referenced and remove the code and subsequently all symbols, which are not referenced after removing it. – Ctx Jan 21 '16 at 15:54