有没有办法知道模板函数或C ++中的类的编译器实例化代码
假设我有以下代码
template < class T> T add(T a, T b){
return a+b;
}
现在我打电话
add<int>(10,2);
我想知道编译器为int特定版本创建的函数。
我正在使用G ++,VC ++。如果有些人可以帮我指出编译器选项来实现这一点,将会很有帮助。
希望问题很清楚。提前谢谢。
答案 0 :(得分:31)
如果要查看装配输出,请使用:
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;
(我通过引用传递参数以使输出更有趣)
答案 1 :(得分:28)
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输出:
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);
}
答案 2 :(得分:20)
您可以使用“-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
这实际上只是一个int添加(leal)。
现在,如何解码c ++名称mangler?有一个名为c ++ filt的实用程序,你粘贴规范(C等效)名称,你得到解码的c ++等价物
qdot@nightfly /dev/shm $ c++filt
_Z3addIiET_S0_S0_
int add<int>(int, int)
答案 3 :(得分:3)
最简单的方法是检查生成的程序集。您可以使用-S标记获取g ++。
答案 4 :(得分:2)
当优化器完成其行为时,您很可能没有任何东西看起来像函数调用。在你的具体例子中,你肯定最终会有一个内联添加,更糟糕的是。除此之外,您始终可以在编译期间在单独的文件中发出生成的汇编程序,这就是您的答案。
答案 5 :(得分:1)
如果您正在寻找等效的C ++代码,那么没有。编译器永远不会生成它。编译器直接生成它的中间表示比生成c ++更快。
答案 6 :(得分:1)
现在有一个在线工具可以为您执行此操作:https://cppinsights.io/例如,此代码
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));
}
答案 7 :(得分:0)
我认为c++ Insights是您想要的。