【问题标题】:Is there a standard way to ensure that a piece of code is executed at global scope?是否有一种标准方法可以确保在全局范围内执行一段代码?
【发布时间】:2017-01-27 10:12:13
【问题描述】:

我想在全局范围内执行一些代码。所以,我可以像这样在编译单元中使用全局变量:

int execute_global_code();
namespace {
int dummy = execute_global_code();
}

问题是,如果这个编译单元最终在一个静态库中(或与-fvisibility=hidden 共享的库),链接器可能会决定删除dummy,因为它没有被使用,而我的全局代码执行。

所以,我知道我可以根据特定的上下文使用具体的解决方案:特定的编译器(pragma include)、编译单元位置(属性可见性默认值)、周围的代码(比如说,在我的代码)。

问题是,是否有一种标准方法可以确保execute_global_code 将被执行,该方法可以适合单个宏,无论编译单元放置(可执行文件还是lib)都可以工作?即:只有标准 c++,并且在该宏之外没有用户代码(就像在 main() 中虚拟使用 dummy

【问题讨论】:

  • 在您的描述中,您已经排除了解决问题的各种方法的可能性。为什么你坚持初始化dummy 的代码必须适合单个宏?
  • @Peter 因为否则“在 main 中虚拟使用 dummy”将是解决方案。关键是我不想用显式初始化代码给库用户增加负担。
  • @grek40 这是一个特定于编译器的解决方案。这是我可能需要使用的东西,但我希望找到一个标准的 C++ 解决方案(如果存在),而不必#if-检查各种编译器或将各种编译器设置强加给库用户
  • 加上@grek40 所说的内容,听起来好像Schwartz/Nifty Counter 可能就是您正在寻找的东西。

标签: c++


【解决方案1】:

问题是链接器将使用所有目标文件来直接链接给它的二进制文件,但对于静态库,它只会拉取那些定义了当前未定义符号的目标文件。

这意味着,如果静态库中的所有目标文件仅包含此类自注册代码(或其他未从被链接的二进制文件中引用的代码),则不应使用整个静态库中的任何内容!

对于所有现代编译器都是如此。没有独立于平台的解决方案。

可以在here 找到使用 CMake 规避此问题的源代码非侵入性方法 - 阅读更多相关信息 here - 如果不使用预编译头文件,它将起作用。用法示例:

doctest_force_link_static_lib_in_target(exe_name lib_name)

有一些特定于编译器的方法可以做到这一点,因为 grek40 已经在评论中 pointed out

【讨论】:

    猜你喜欢
    • 2019-01-23
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多