我们能看到C++编译器示例化的模板代码吗

dz6r00yl  于 2023-02-10  发布在  其他
关注(0)|答案(8)|浏览(141)

有没有一种方法可以知道编译器示例化的C++中模板函数或类的代码
假设我有下面的代码

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

现在当我打电话

add<int>(10,2);

我想知道编译器为int特定版本创建的函数。
我正在使用G++,VC++。如果有人能帮我指出实现这一点的编译器选项,那将会很有帮助。
希望问题问清楚了。先谢了。

wlwcrazw

wlwcrazw1#

Clang(https://clang.llvm.org/)可以漂亮地打印示例化模板的AST:
对于您的示例:

  • 测试.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

叮当声-5.0/叮当声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);
}
wz3gfoph

wz3gfoph2#

如果要查看程序集输出,请使用以下命令:

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;

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

gcxthw6b

gcxthw6b3#

使用“-S”选项可以清楚地看到g生成的汇编代码。
我认为不可能显示“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

它实际上只是一个整型加法(leal)。
现在,如何解码c++ name mangler?有一个名为cfilt的实用程序,您粘贴规范(C等价)名称,然后获得解角的c等价

qdot@nightfly /dev/shm $ c++filt 
_Z3addIiET_S0_S0_ 
int add<int>(int, int)
l2osamch

l2osamch4#

现在有一个在线工具可以帮你做到这一点: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));
}
lhcgjxsq

lhcgjxsq5#

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

g6baxovj

g6baxovj6#

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

ohfgkhjo

ohfgkhjo7#

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

相关问题