【问题标题】:C++ inner class; no symbol in "nm -C" outputC++内部类; “nm -C”输出中没有符号
【发布时间】:2015-06-10 05:00:12
【问题描述】:

我正在通过gcc 4.8.1 在 Linux 上使用选项 -frepo 研究 C++ 模板实例化的详细信息。据我了解,此选项对模板实例化进行了一些内部清理,因此每个实例化仅在链接的二进制文件中出现一次,即使它在多个翻译单元中隐式实例化也是如此。具体上下文请参考以下示例文件:

// file: template.h
template <typename T>
class Box {
public:
    void func (const T & t) {}        // member function

    template <T t>
    T func_tmpl () { return t; }      // member function template

    template <T t>
    class inner {                     // inner class template
    public:
        const static T value = t;
    };
};

// file: main.cpp
#include "template.h"

int main (int argc, char * argv[]) {
    Box<int> b;
    b.func(3);                        // member function invocation
    int x = b.func_tmpl<7>();         // member function temple instantiation
    Box<int>::inner<5> g;             // inner class template instantiation
    int y = g.value;
    return 0;
}

当我编译 (g++ -frepo -c main.cpp) 然后检查符号 (nm -C main.o) 时,我发现:

0000000000000000 T main
                 U Box<int>::func(int const&)
                 U int Box<int>::func_tmpl<7>()

如您所料,funcfunc_tmpl 被列为未定义符号。我不清楚的是为什么inner 也没有列出;它在类模板中定义,本身就是类模板,并在main.cpp 中实例化。任何人都可以提出inner 未包含在main.o 符号中的原因,无论是否定义?

【问题讨论】:

  • nm 不显示类,它显示函数和全局变量。它会显示Box&lt;int&gt;::inner&lt;5&gt;::value,只是这里“未使用”。
  • @MarcGlisse 感谢您的快速回复。您评论的第一句话似乎很合理,并且可以解释事情。不过,我对第二句话很好奇:我如何让它“使用”?我尝试了几种方法都没有明显效果。另外,Box&lt;int&gt;::inner&lt;5&gt;::value 实际上是一个全局变量吗?我会认为它的范围更窄,因为需要:: 来识别它。再次感谢!

标签: c++ templates gcc inner-classes


【解决方案1】:

编译器发现Box&lt;int&gt;::inner&lt;5&gt;::value 是一个常量,目标代码生成将其取出并用文字5 替换名称。如果您观察生成的汇编代码,您可能会看到如下内容:

    movl    $3, -12(%rbp)
    leaq    -12(%rbp), %rdx
    leaq    -13(%rbp), %rax
    movq    %rdx, %rsi
    movq    %rax, %rdi
    call    _ZN3BoxIiE4funcERKi
    leaq    -13(%rbp), %rax
    movq    %rax, %rdi
    call    _ZN3BoxIiE9func_tmplILi7EEEiv
    movl    %eax, -4(%rbp)
    movl    $5, -8(%rbp)

这对应于对Box::func的调用,然后是对Box::func_tmpl的调用分配给x,然后是对y的分配。请注意,对 y 的赋值使用文字值 5

要使符号出现在您的nm 输出中,请使用成员本身,而不是其值。例如,存储它的引用:

    const int &y = g.value;

【讨论】:

  • 感谢您的详细回答。我没有考虑持续优化。多亏了你,下次我会注意寻找的。我试图对你的答案投赞成票,但显然我首先需要更高的声誉。
猜你喜欢
  • 2021-06-07
  • 2020-02-06
  • 2011-04-09
  • 1970-01-01
  • 2019-05-31
  • 2016-09-28
  • 2013-12-23
  • 2021-06-24
  • 1970-01-01
相关资源
最近更新 更多