C++ 内部 class; "nm -C" 输出中没有符号
C++ inner class; no symbol in "nm -C" output
我正在研究 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>()
如您所料,func
和 func_tmpl
被列为未定义的符号。我不清楚的是为什么 inner
也没有列出;它在 class 模板中定义,本身就是一个 class 模板,并在 main.cpp
中实例化。谁能提出 inner
未包含在 main.o
符号中的原因,定义与否?
编译器发现Box<int>::inner<5>::value
是一个常量,目标代码生成将其取出并用文字5
替换了名称。如果您观察生成的汇编代码,您可能会看到如下内容:
movl , -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 , -8(%rbp)
对应调用Box::func
,然后调用Box::func_tmpl
赋值给x
,然后赋值给y
。请注意,对 y
的赋值使用文字值 5
.
要使符号出现在您的 nm
输出中,请使用成员本身,而不是其值。例如,存储它的引用:
const int &y = g.value;
我正在研究 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>()
如您所料,func
和 func_tmpl
被列为未定义的符号。我不清楚的是为什么 inner
也没有列出;它在 class 模板中定义,本身就是一个 class 模板,并在 main.cpp
中实例化。谁能提出 inner
未包含在 main.o
符号中的原因,定义与否?
编译器发现Box<int>::inner<5>::value
是一个常量,目标代码生成将其取出并用文字5
替换了名称。如果您观察生成的汇编代码,您可能会看到如下内容:
movl , -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 , -8(%rbp)
对应调用Box::func
,然后调用Box::func_tmpl
赋值给x
,然后赋值给y
。请注意,对 y
的赋值使用文字值 5
.
要使符号出现在您的 nm
输出中,请使用成员本身,而不是其值。例如,存储它的引用:
const int &y = g.value;