【问题标题】:g++ produces empty object fileg++ 产生空的目标文件
【发布时间】:2012-02-15 22:33:27
【问题描述】:

我正在尝试将一个基本的数组包装模板类编译到一个 .o 文件中,以尝试弄清楚如何制作动态库。但是,当使用

编译源代码时
g++ -std=c++0x -c array.cpp

生成的文件只有 ~650 字节。我用 nm 检查了文件,发现它包含的唯一符号是

00000001 r _ZStL13allocator_arg
00000000 r _ZStL19piecewise_construct

这似乎是 C++11 编译的特性,因为在没有 -std=c++0x 标志的情况下编译它们就消失了。

试图编译程序测试代码和所有的命令

g++ -std=c++0x -o tester tester.cpp array.cpp

为 array.cpp 中的所有内容产生链接器错误,但编译干净。

老实说,我不知道这是怎么回事。如果您怀疑这是我的代码本身的问题,而不是我的编译方式,我可以发布 array.cpp 和 array.hpp 的内容。

【问题讨论】:

  • 您正在尝试编译未实例化的模板?
  • 模板不是代码,而是代码生成工具。只有实际的代码被编译。
  • 在tester.cpp中实例化为array;我只尝试在没有 tester.cpp 的情况下进行编译,以便弄清楚为什么我在第二个(按时间顺序排列)编译命令中出现链接器错误,尽管所有函数都在 .cpp 中。
  • 模板定义必须放在头文件中。未实例化的模板不是代码,因此不会向目标文件添加任何内容。
  • 啊。我现在觉得自己像个白痴 X|;我会试试的。

标签: c++ compiler-construction linker g++ c++11


【解决方案1】:

这很正常。模板只有在它们被实例化时才会产生代码,而你还没有这样做。您只提供了模板。编译器在编译模板时,没有理由生成模板的任何特定实例,其中为模板参数填充了实际类型。

稍后,编译器会编译您使用模板类型的其他源文件。这也不会导致实例化。它只是告诉编译器它应该期望在其他地方找到模板的实例。编译器在目标文件中说明了这一点。链接器然后查找编译器说它应该找到的定义,但它失败了。

这就是为什么总是建议您在标头中提供与声明内联的模板定义的原因。这样,当编译器看到您使用模板时,它可以立即使用它在标头中看到的定义来实例化模板。如果您在多个源文件中使用模板,您可能会因多次实例化模板而得到多个定义,但这是允许的,并且链接器知道如何处理它。

另一种方法是在 array.cpp 文件中显式实例化模板,但内联定义模板成员更容易。

【讨论】:

  • 非常有帮助.. 花了很多时间才找到这个。
  • 您能否提供一个示例,说明在声明中提供模板的内联声明的好方法?
  • main example in documentation,@Warren。声明紧随其后实施。 (main 在同一个文件中的存在在这里无关紧要。)
【解决方案2】:

如果 array.cpp 只包含模板,你不需要单独编译它,你可能称之为 array.hpp。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多