C++ 我们可以看到C++;编译程序

C++ 我们可以看到C++;编译程序,c++,C++,有没有办法知道C中模板函数或类的编译器实例化代码++ 假设我有以下代码 template < class T> T add(T a, T b){ return a+b; } 模板T添加(T a,T b){ 返回a+b; } 现在当我打电话的时候 add<int>(10,2); add(10,2); 我想知道编译器为int特定版本创建的函数 我用的是G++,VC++。如果有人能帮我指出实现这一点的编译器选项,那将是很有帮助的 希望问题清楚。

有没有办法知道C中模板函数或类的编译器实例化代码++

假设我有以下代码

template < class T> T add(T a, T b){
            return a+b;
}
模板T添加(T a,T b){
返回a+b;
}
现在当我打电话的时候

add<int>(10,2); 
add(10,2);
我想知道编译器为int特定版本创建的函数

我用的是G++,VC++。如果有人能帮我指出实现这一点的编译器选项,那将是很有帮助的


希望问题清楚。提前感谢。

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

当优化器完成了它的工作后,您很可能已经没有任何类似于函数调用的东西了。在您的特定示例中,您最终肯定会得到一个内联加法,甚至更糟。除此之外,在编译过程中,您始终可以在单独的文件中发出生成的汇编程序,答案就在这里。

您肯定可以看到g++使用“-S”选项生成的汇编代码

我认为不可能显示“C++”等价的模板代码——但我仍然希望g++开发人员插话解释原因——我不知道gcc的体系结构

使用汇编时,您可以查看生成的代码,查找与您的函数相似的内容。由于运行了gcc-S-O1{yourcode.cpp},我得到了这个(AMD64,gcc4.4.4)

这实际上只是一个整数加法(leal)

<>现在,如何解码C++名字mangler?有一个实用工具叫做C++ FLT,你粘贴规范(C等价)名称,得到的是与C++等价的

qdot@nightfly /dev/shm $ c++filt 
_Z3addIiET_S0_S0_ 
int add<int>(int, int)
qdot@nightfly/dev/shm$c++filt
_Z3ADDIET_S0_S0_
整数加(整数,整数)

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

g++ -S file.cpp
g++ -fdump-tree-original file.cpp

如果你想看到GCC生成的一些(伪)C++代码,你可以使用这个:

g++ -S file.cpp
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;
;;函数T add(常数T&,常数T&)[带T=int](null)
;; 由原始树启用
返回=(int)*l+(int)*r;

(通过引用,我通过参数使输出稍微有意思)

如果你寻找等价的C++代码,则不。编译器永远不会生成它。编译器生成中间表达式的速度比生成C++的速度快得多。

< P> Clang()可以实例化模板的漂亮打印AST:

例如:

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);
}
模板T添加(T a,T b){
返回a+b;
}
模板整数添加(整数a、整数b){
返回a+b;
}
void tmp(){
增加(10,2);
}

现在有一个在线工具可以为您执行此操作:例如,此代码

template<class X, class Y> auto add(X x, Y y) {
  return x + y;
}

int main()
{
  return add(10, 2.5);
}
模板自动添加(X,Y){
返回x+y;
}
int main()
{
返回添加(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));
}
模板自动添加(X,Y){
返回x+y;
}
/*首先实例化自:insights.cpp:9*/
#ifdef洞察\u使用\u模板
模板
双加(整数x,双y)
{
返回静态_型(x)+y;
}
#恩迪夫
int main()
{
返回静态_-cast(添加(10,2.5));
}

<>代码> 我想是你想要的。< /p>你想在C++中还是在汇编中看到函数?如果在汇编中,请使用
g++-S
。一个密切相关的问题:您想要什么如果允许人们查看生成的模板代码,那么无论如何都可能太多而无法阅读。。。在STLWELL的情况下,人们可以看到生成的程序集,这已经相当多了,但是,有时它只是需要获得有价值的洞察力。@ QDOT,看到汇编和C++生成代码完全不同。有时,您希望通过使用类型化器生成类的层次结构,然后您可能需要将结果视为C++代码,以便在层次结构中确定。在这种情况下,汇编毫无帮助。我相信这是OP寻找的最佳答案(与其他备选方案相比)。这应该是公认的答案。多么伟大的发现啊!作者解释了C++的见解是基于CLAN的,但是它自己的许多工作,产生了比C++中更完美、更理想的C++可编译的中间代码。它还为
循环生成“原始”版本,如基于范围的
。非常激动人心@是的,我也认为它是一个很棒的工具,在某些情况下非常有用。至于被接受的答案-是的,这将是很好的可见性,因为人们可以辩论漂亮的打印AST,我100%相信它比目前被接受的ASM的答案更好。
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));
}