有没有办法在C++中查看模板函数或类的编译器实例化代码?
假设我有以下代码:
template < class T> T add(T a, T b){
return a+b;
}
现在当我调用时
add<int>(10,2);
我希望能够查看编译器为int
模板特化创建的函数。
我正在使用g++、VC++。如果有人能指出实现此目的的编译器选项,那将非常有帮助。
希望问题清晰明了。谢谢提前。
有没有办法在C++中查看模板函数或类的编译器实例化代码?
假设我有以下代码:
template < class T> T add(T a, T b){
return a+b;
}
add<int>(10,2);
我希望能够查看编译器为int
模板特化创建的函数。
我正在使用g++、VC++。如果有人能指出实现此目的的编译器选项,那将非常有帮助。
希望问题清晰明了。谢谢提前。
Clang(https://clang.llvm.org/)可以漂亮地打印出实例化模板的AST:
以您的示例为例:
test.cpp
template < class T> T add(T a, T b){
return a+b;
}
void tmp() {
add<int>(10,2);
}
美化AST的命令:
$ clang++ -Xclang -ast-print -fsyntax-only test.cpp
Clang-5.0/Clang 14.0 输出:
template <class T> T add(T a, T b) {
return a + b;
}
template<> int add<int>(int a, int b) {
return a + b;
}
void tmp() {
add<int>(10, 2);
}
如果您想查看汇编输出,请使用以下命令:
g++ -S file.cpp
如果你想查看GCC生成的一些(伪)C++代码,你可以使用以下方法:
g++ -fdump-tree-original file.cpp
对于您的add
函数,它将输出类似于以下内容:
;; Function T add(const T&, const T&) [with T = int] (null)
;; enabled by -tree-original
return <retval> = (int) *l + (int) *r;
template<class X, class Y> auto add(X x, Y y) {
return x + y;
}
int main()
{
return add(10, 2.5);
}
被翻译成
template<class X, class Y> auto add(X x, Y y) {
return x + y;
}
/* First instantiated from: insights.cpp:9 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
double add<int, double>(int x, double y)
{
return static_cast<double>(x) + y;
}
#endif
int main()
{
return static_cast<int>(add(10, 2.5));
}
通过使用"-S"选项,您绝对可以看到g++生成的汇编代码。
我认为不可能显示等效于"C ++"模板代码的内容 - 但我仍希望g ++开发人员介入说明原因 - 我不了解gcc的架构。
当使用汇编语言时,您可以查看生成的代码,寻找类似于您函数的部分。运行gcc -S -O1 {yourcode.cpp}后,我得到了这个(AMD64,gcc 4.4.4)。
_Z3addIiET_S0_S0_:
.LFB2:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
leal (%rsi,%rdi), %eax
ret
.cfi_endproc
这实际上只是一个整数加法(leal)。
现在,如何解码C++名称修饰器?有一个叫做c++filt的工具,你可以粘贴规范化(等效于C语言)的名称,然后得到对应的C++名称。
qdot@nightfly /dev/shm $ c++filt
_Z3addIiET_S0_S0_
int add<int>(int, int)
g++ -S
。 - mtvec