Search code examples
cc99dead-code

Dead code removal of extern'd global


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.


Solution

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