【问题标题】:linkage fails when referencing a constructor引用构造函数时链接失败
【发布时间】:2018-08-07 16:23:58
【问题描述】:

我有两个源文件,其中一个有一个来自我自己的类的静态成员 foo。当我将其编译为目标文件时,编译器会生成一个 .ctors 部分,并在其中生成一个调用构造函数的函数,我们将其称为 _GLOBAL__SUB_I_FOO。

在第二个源文件中,我尝试自己调用这个构造函数:

int _GLOBAL__SUB_I_FOO();
int bar(){
   _GLOBAL__SUB_I_FOO();
}

当我链接这两个对象时,第二个文件中存在对 _GLOBAL__SUB_I_FOO 的未定义引用。 当我使用 --relocatable 链接查看出了什么问题时,我可以看到原始构造函数已重命名为 _GLOBAL__SUB_I_FOO_0 以避免“碰撞”(这是故意的)。我能做些什么来修复它? 我正在使用 gcc 7.3.0

【问题讨论】:

  • 为什么不直接调用构造函数(创建对象)?
  • 是静态对象的构造函数
  • 是编译器创建了这个函数_GLOBAL__SIB_I_FOO还是你写的函数?
  • 你为什么还要调用这个函数?在我看来,它应该作为实现细节保持隐藏。
  • 鉴于函数的名称是为实现保留的名称,很明显您应该自己调用它(即使 if i> 你在技术上可以)。

标签: c++ gcc ld


【解决方案1】:

要执行之前在静态对象的构造函数中的代码,请将其移动到 init() 函数中,然后从构造函数(以及您需要它的任何其他地方)调用它。

【讨论】:

  • 这是可能的,但不是我正在寻找的答案,我正在寻找更封闭的解决方案,让我可以调用任何 ctor 而无需在另一个函数中实现它。不过,谢谢。
  • 静态对象的问题在于,它们是由实现决定的一次构造一次。它是一个对象,因此只能构造一次。也许你会从基于Singleton 模式的东西中获得更好的里程
  • 如果你想知道,我实际上是在实现调用构造函数的机制。只是..跟我一起做这个,我知道这不是标准的,但必须有办法做到这一点。
  • 我不认为 gcc 7.3.0 与“跟我一起去”兼容。它总是会为其内部函数选择一个唯一的名称,并且它总是会在对代码进行任何更改之后这样做。如果你偶然发现了一个 hack,也许是通过放入一个相邻的对象并相对于它的地址跳转,那么这个 hack 仍然容易在任何其他编译器或该编译器的其他版本上失败。我只是认为你试图做的事情......是错误的。
  • 你这样说是因为你知道,还是你的感觉?因为 ld 知道这是一个内部函数对我来说很奇怪 - 如果它知道,则必须有一种方法将其标记为“正常”函数。我不是在寻找黑客,它只是从不同的对象调用一个函数。
猜你喜欢
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 2015-06-28
  • 2011-01-21
  • 1970-01-01
  • 2016-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多