2016-01-20 64 views
2

我想知道编译器/链接器是否会删除已在公共头文件中的全局变量extern'd?例如:移除外部全局的死代码

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

extern const struct func_ptrs DEFAULT_FUNCS; 

和:

// 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 }; 

是否有任何特定的链接器标记,将允许该变量(和两个函数)从所得到的二进制剥离?

假定GCC和MSVC作为两个目标编译器。

+1

看看这里:http://stackoverflow.com/questions/6687630/how-to-remove-unused-cc-symbols-with-gcc-and-ld – nsilent22

回答

0

DEFAULT_FUNCS:

由于符号DEFAULT_FUNCS - 由于其范围和改性剂 - 受出口到二进制的符号表(动态)连接,它不能被剥离。换句话说:链接器(ld)不能确定符号是否被使用。

功能def_foo & def_bar

此外,在所有可能被剥离没有的功能,因为你只宣布他们。事实上,链接此二进制文件将失败,因为def_foodef_bar是未定义的符号。

一两件事:正确的是:

const struct func_ptrs DEFAULT_FUNCS = ... 

没有星号,因为你初始化一个结构,而不是一个指针。

+0

我更新了原来的职位,以承担功能是实现。无论如何,在链接过程中'-flto'是否有助于剥离? – MarkP

+0

这取决于。如果符号位于动态符号表(选项-rdynamic)中,则链接时间优化程序无法删除它,因为它不知道它是否会在运行时链接。使用标准选项,它可以检测到符号DEFAULT_FUNCS未被引用,并删除代码,并随后删除所有符号,删除后不会引用它们。 – Ctx