【问题标题】:Any way to tell linker to "respect" __attribute__((__used__))告诉链接器“尊重”的任何方式 __attribute__((__used__))
【发布时间】:2019-04-25 18:22:27
【问题描述】:

我正在尝试解决链接器在我的代码中删除注册的事实。 有关详细信息,请参阅此answer

我对这个答案的问题是 --whole-archive 选项对于仅 1 个函数调用似乎有点过头了。我想避免我认为它导致的巨大代码膨胀。 我找到了

属性((使用))

,但这适用于编译,而不是链接级别。

所以我想知道是否有一种特定的方法可以告诉链接器不要放弃特定的函数调用,而不是更改整个程序的链接选项。

为了澄清,这是我的代码:

bool dummy = (Register(), false); // Register is never called because linker dropped entire static library

【问题讨论】:

  • “放弃注册”是什么意思?此外,链接器行为的细节是特定于实现的,那么您使用的是哪个实现?海湾合作委员会,也许吧?
  • @JohnBollinger 链接的答案提供了更长的解释......简而言之,我有 bool dummy = (Register("Something1"), false);并且链接器会删除整个库,因此永远不会调用 Register()
  • 不清楚您描述的情况是否与您参考的答案相似。特别不清楚链接器是否对您的案例中涉及的(错误)行为负责,此外,解决方案的最佳选择很可能取决于上下文。所以请提供一个 minimal reproducible example 来证明这个问题。
  • 这个问题被标记为shared-libraries,但从帖子本身很明显它应该被标记为static-libraries。改变了。

标签: c++ c linker static-libraries


【解决方案1】:

所以我想知道是否有一种特定的方法可以告诉链接器不要放弃特定的函数调用,而不是更改整个程序的链接选项。

您的目标实际上是告诉链接器不要将未引用变量的定义 (dummy) 初始化程序有一个函数调用,您希望确保由您的程序执行。

__attribute__(used)是函数的属性,而不是变量的属性,其作用是强制编译器编译函数定义, 即使该函数是静态的并且在翻译单元中显示为未引用。在你的情况下:

bool dummy = (Register(), false);

在编译器看来,Register 没有被引用——它被调用——所以__attribute__(used) 将 即使Register() 的定义在同一个翻译单元中并且是静态的,也是多余的。但无论是 不是Register() 的定义是在这个翻译单元或其他一些编译单元中编译的,这个调用Register() 如果dummy的这个定义没有被链接,将不会在程序中链接或执行。

我假设您不想编写自定义链接器脚本,或修改源代码以便引用 dummy

在这种情况下,您需要指示链接器假设dummy 的未定义引用,通过 在其选项中传递--undefined=dummy。这将迫使它搜索库 dummy 的定义,并准确链接存档成员(和/或共享库) 实际上是链接的第一个文件中对dummy 的未定义引用。不会链接冗余代码, 就像--whole-archive 一样。

您可以将--undefined=<symbol> 传递给链接器,以获得与<symbol> 一样多的值 你喜欢。要将其传递给gcc/g++,请使用-Wl,--undefined=<symbol>

【讨论】:

    【解决方案2】:

    把它放在它自己的部分和链接描述文件中:

    KEEP(sectionname)
    

    编辑

    这行代码可能会简化为将一个寄存器或变量归零

    【讨论】:

      猜你喜欢
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-22
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多