在C++中,有没有一种方法可以看到函数模板或类模板的编译器示例化代码?假设我有以下代码:
template <class T> T add(T a, T b) { return a + b; }
当我打电话:
add<int>(10, 2);
...我想看看编译器为int模板专门化创建的函数。我正在使用g++,VC++,需要知道编译器选项来实现这一点。
int
ecfsfe2w1#
Clang(https://clang.llvm.org/)可以漂亮打印示例化模板的AST:例如:
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); }
vwkv1x7d2#
如果你想看到程序集的输出,使用这个:
g++ -S file.cpp
如果你想看到一些GCC生成的(伪)C++代码,你可以使用这个:
g++ -fdump-tree-original file.cpp
对于您的add函数,这将输出如下内容
add
;; Function T add(const T&, const T&) [with T = int] (null) ;; enabled by -tree-original return <retval> = (int) *l + (int) *r;
(我通过引用传递参数,使输出更有趣一点)
c6ubokkw3#
您可以肯定地看到g使用“-S”选项生成的汇编代码。我认为不可能显示“C”等效的模板代码--但我仍然希望g++开发人员插话,为什么--我不知道gcc的体系结构。使用汇编时,可以查看生成的代码,查找与函数相似的内容。作为运行gcc -S -O 1 {yourcode.cpp}的结果,我得到了这个(AMD 64,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?有一个叫做cfilt的实用程序,你粘贴规范的(C等价的)名称,你就可以得到去角的c++等价的
qdot@nightfly /dev/shm $ c++filt _Z3addIiET_S0_S0_ int add<int>(int, int)
epggiuax4#
现在有一个在线工具可以为您做到这一点: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)); }
sh7euo9m5#
当优化器完成它的工作时,您很可能没有留下任何看起来像函数调用的东西。在您的特定示例中,您肯定会以内联添加结束,甚至更糟。除此之外,在编译过程中,您总是可以在单独的文件中发出生成的汇编程序,这就是您的答案。
kcrjzv8t6#
最简单的方法是检查生成的程序集。您可以通过对g++使用-S标志来获得汇编源代码。
wh6knrhe7#
如果你正在寻找等价的C代码,那么没有。编译器永远不会生成它。编译器直接生成它的中间表示比先生成c要快得多。
lbsnaicq8#
我想c++ Insights是你想要的。
8条答案
按热度按时间ecfsfe2w1#
Clang(https://clang.llvm.org/)可以漂亮打印示例化模板的AST:
例如:
命令来漂亮地打印AST:
Clang-5.0/Clang 14.0输出:
vwkv1x7d2#
如果你想看到程序集的输出,使用这个:
如果你想看到一些GCC生成的(伪)C++代码,你可以使用这个:
对于您的
add
函数,这将输出如下内容(我通过引用传递参数,使输出更有趣一点)
c6ubokkw3#
您可以肯定地看到g使用“-S”选项生成的汇编代码。
我认为不可能显示“C”等效的模板代码--但我仍然希望g++开发人员插话,为什么--我不知道gcc的体系结构。
使用汇编时,可以查看生成的代码,查找与函数相似的内容。作为运行gcc -S -O 1 {yourcode.cpp}的结果,我得到了这个(AMD 64,gcc 4.4.4)
它实际上只是一个int加法(leal)。
现在,如何解码c名称mangler?有一个叫做cfilt的实用程序,你粘贴规范的(C等价的)名称,你就可以得到去角的c++等价的
epggiuax4#
现在有一个在线工具可以为您做到这一点:https://cppinsights.io/例如,以下代码
被翻译成
sh7euo9m5#
当优化器完成它的工作时,您很可能没有留下任何看起来像函数调用的东西。在您的特定示例中,您肯定会以内联添加结束,甚至更糟。除此之外,在编译过程中,您总是可以在单独的文件中发出生成的汇编程序,这就是您的答案。
kcrjzv8t6#
最简单的方法是检查生成的程序集。您可以通过对g++使用-S标志来获得汇编源代码。
wh6knrhe7#
如果你正在寻找等价的C代码,那么没有。编译器永远不会生成它。编译器直接生成它的中间表示比先生成c要快得多。
lbsnaicq8#
我想c++ Insights是你想要的。