据我了解,函数级链接构建(显式或不显式)所有可能调用的图表,并且仅将可访问函数的代码包含到生成的二进制文件中。但是它如何处理在文件级别声明的变量呢?
说我有
MyClass GlobalVariable;
static MyClass StaticGlobalVariable;
在一些只包含这两个变量和一组函数的文件中,这些函数实际上并未从任何剩余的代码中调用。
这些变量分配/初始化的代码是否会包含在输出中?
据我了解,函数级链接构建(显式或不显式)所有可能调用的图表,并且仅将可访问函数的代码包含到生成的二进制文件中。但是它如何处理在文件级别声明的变量呢?
说我有
MyClass GlobalVariable;
static MyClass StaticGlobalVariable;
在一些只包含这两个变量和一组函数的文件中,这些函数实际上并未从任何剩余的代码中调用。
这些变量分配/初始化的代码是否会包含在输出中?
根据经验(而不是引用标准):
如果初始化具有可见的副作用,例如调用外部库或文件 I/O,则初始化将始终发生。
boost::singleton_default提供了一个有趣的解决方案,它强制只在对象被其他地方引用时才进行初始化,即当链接器删除对该对象的所有其他引用时,初始化也被删除。
编辑:是的。g++ 优化标志尝试找出函数调用并修剪掉导致链接器错误的 .o 文件。我不确定这是否只发生在某些优化标志上,但确实会发生。
我们公司的一个坏习惯是在不同的文件中存在大量的“extern g_GlobalFunction()”定义。由于他们的调用依赖于条件代码,.o 文件经常被丢弃,导致链接错误。
我们通过从 main() 开始分层调用的 g_InitModule() 和 g_InitFileName() 调用修复了这个问题。大多数情况下,这些都是空函数,只是为了阻止 g++ 丢弃 .o 文件。