C++函数模板在汇编中是如何实现的?

5

我正在尝试使用汇编代码(具体来说是ARMv7-a)来实现C++函数。现在我遇到了一个问题,我不知道如何在汇编中实现C++函数模板。我尝试使用-S -O1标志编译源代码以查看生成的汇编代码,但无法理解它。有人能简要说明一下C++模板如何转换为汇编代码吗?以下是一个简单函数的例子:

template<typename T>
T f(T a) {
   return a + 1;
}

如果您发现其他函数更容易解释,请使用该函数。谢谢!

你想要返回一个 T,而不是 void。 - SwiftMango
使用编译器编译一个简单的示例,其中包含几种不同类型的模板参数,并查看它生成的汇编代码。这应该能让你很好地了解汇编代码的样子。如果你不理解输出结果,你应该寻求帮助来解决问题。 - mah
1
一个有用的技巧是嵌入注释,比如 asm("#begin template"),这样会在 .s 文件中显示。 - Anycorn
现代编译器在生成优化的汇编代码方面表现出色。我并不质疑您的个人专业知识,但试图超越编译器进行优化似乎是一项回报微小且非常困难的任务。 - Dan Korn
@DanKorn 他可能只是想玩一下,这是一个非常合理的原因去做这件事。 - maxywb
我真的很惊讶人们在这里的回应速度。非常感谢你们,对于代码中的错误我很抱歉。我之所以问这个问题是因为我将使用ARM的NEON指令来加速程序,该程序操作寄存器向量而不是普通寄存器。而且要实现的函数是用函数模板编写的(感谢Nikos),这就是我提出问题的原因。我认为在此处分别实现模板的每个实例是我要做的事情。 - Da Teng
2个回答

11

正确表述会有所帮助。它不是模板函数,而是函数模板...注意区别吗?

模板是在实例化时生成代码的。因此,在这种情况下,如果您将f实例化为int,汇编代码将与...

int f(int a) { // Note that having a return type void is wrong here
   return a + 1;
}

非实例化模板缺乏二进制代码生成,这就是为什么模板代码中的许多错误在执行有问题的类型的实例化之前都会处于休眠状态。

因此,以下是一个真实示例,包括两个版本:一个是函数模板生成的,另一个是函数生成的(均为int);如果不是右侧提示,则无法区分它们之间的差异:

    f2(1);
00BA25BE  push        1  
00BA25C0  call        f2<int> (0BA12F3h)  
00BA25C5  add         esp,4  
    f(1);
00BA25C8  push        1  
00BA25CA  call        f (0BA12EEh)  
00BA25CF  add         esp,4  

有关模板(这次是类型)和二进制代码表示的更多信息在这里


实现必须检查函数模板,例如语法错误,即使它们没有被实例化。 - juanchopanza
@juanchopanza 是的,好的基本语法检查;我强调了休眠错误以显示未实例化类型的代码生成缺失。您是否建议重新表述或者我应该补充语法检查的存在? - Nikos Athanasiou
2
这不仅仅是基本的语法检查。非依赖名称也被查找。最好完全删除该行,因为它很复杂! - juanchopanza

6

你应该在单独的程序集中实现每个模板实例。

从根本上讲,每个模板实例都是不同的类型。您还需要处理特化; 部分或其他方式。

(当然,这意味着您需要预先知道需要哪组T,但这基本上就是C ++编译器所做的。)


需要注意的是,模板类型在编译时填充,因此生成的汇编代码完全取决于它所生成的类型。 - maxywb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接