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