gcc 我们可以看到C++编译器示例化的模板吗?

3wabscal  于 2023-06-23  发布在  其他
关注(0)|答案(8)|浏览(151)

在C++中,有没有一种方法可以看到函数模板或类模板的编译器示例化代码?
假设我有以下代码:

template <class T> T add(T a, T b) {
    return a + b;
}

当我打电话:

add<int>(10, 2);

...我想看看编译器为int模板专门化创建的函数。
我正在使用g++,VC++,需要知道编译器选项来实现这一点。

ecfsfe2w

ecfsfe2w1#

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);
}
vwkv1x7d

vwkv1x7d2#

如果你想看到程序集的输出,使用这个:

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;

(我通过引用传递参数,使输出更有趣一点)

c6ubokkw

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)
epggiuax

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));
}
sh7euo9m

sh7euo9m5#

当优化器完成它的工作时,您很可能没有留下任何看起来像函数调用的东西。在您的特定示例中,您肯定会以内联添加结束,甚至更糟。除此之外,在编译过程中,您总是可以在单独的文件中发出生成的汇编程序,这就是您的答案。

kcrjzv8t

kcrjzv8t6#

最简单的方法是检查生成的程序集。您可以通过对g++使用-S标志来获得汇编源代码。

wh6knrhe

wh6knrhe7#

如果你正在寻找等价的C代码,那么没有。编译器永远不会生成它。编译器直接生成它的中间表示比先生成c要快得多。

相关问题