我想在全球范围内执行一些代码。所以,我可以在编译单元中使用全局变量,如下所示:
int execute_global_code();
namespace {
int dummy = execute_global_code();
}
问题在于,如果此编译单元最终位于静态库(或具有-fvisibility=hidden
的共享库)中,则链接器可能决定消除dummy
,因为它未被使用,以及我的全局代码执行。
所以,我知道我可以根据具体的上下文使用具体的解决方案:特定的编译器(pragma include),编译单元位置(属性可见性默认值),周围的代码(比如说,假装使用dummy
在我的代码中。)
问题是,是否有一种标准方法可以确保execute_global_code
能够适合单个宏,无论编译单元位置(可执行文件或lib)如何都可以使用? ie:只有标准的c ++,并且没有该宏之外的用户代码(比如在dummy
中虚假使用main()
)
答案 0 :(得分:2)
问题是链接器将使用所有目标文件直接链接给它的二进制文件,但对于静态库,它只会提取那些定义当前未定义的符号的目标文件。
这意味着如果静态库中的所有目标文件只包含这样的自注册代码(或者没有从被链接的二进制文件中引用的其他代码) - 则不应使用整个静态库中的任何内容!
所有现代编译器都是如此。没有独立于平台的解决方案。
可以找到使用CMake绕过这种情况的源代码方式的非侵入性here - 阅读更多关于它here - 如果没有使用预编译头,它将起作用。用法示例:
doctest_force_link_static_lib_in_target(exe_name lib_name)
有一些特定于编译器的方法可以做到这一点,因为grek40在评论中已经pointed out。