传普通引用与const引用的编译器行为差异:反汇编为何无区别?
问题:引用与const引用函数调用的反汇编差异原因
编译下方代码并查看反汇编(执行命令objdump -DSs a.out > a.dis)后,发现调用fun_ref(T &)与fun_const_ref(const T &)的过程并无差异。这种无差异是因为参数类型T为std::vector<int>,还是无论参数类型T是什么,调用步骤都不会有区别?
// g++ -std=c++17 -Wall -Wextra -pedantic -Wfatal-errors -Werror example_objdump.cc // objdump -DSs a.out > a.dis #include <iostream> #include <vector> void __attribute__ ((noinline)) fun_ref(std::vector<int> & rv, const int a) { std::cout << rv.at(a) << std::endl; } void __attribute__ ((noinline)) fun_const_ref(const std::vector<int> & crv, const int a) { std::cout << crv.at(a) << std::endl; } int main() { std::vector<int> v(128); volatile int a{3}; v.at(a) = 1; fun_ref(v, a); v.at(a) = 2; fun_const_ref(v, a); return 0; }
回答
无论参数类型T是什么,这两个函数的调用步骤在汇编层面几乎都会完全一致,和std::vector<int>这个类型无关,核心原因有两点:
引用的本质是指针语法糖
C++里的引用在底层就是用指针实现的,传递T&或者const T&,本质都是把对象的内存地址传递给函数——要么压入栈中,要么放入指定寄存器(具体取决于平台的调用约定),传递方式完全相同。const是编译期约束,不影响汇编代码
const修饰符只是告诉编译器:函数内部不能修改引用指向的对象。这个限制只在编译阶段生效,用来检查代码合法性,不会改变参数传递的逻辑,也不会生成额外的汇编指令。
补充说明:如果函数内部因为const修饰调用了不同的成员函数(比如std::vector的at()有const和非const两个版本),那函数内部的汇编代码会有差异,但调用函数的步骤(传参、跳转指令)依然完全相同。
内容的提问来源于stack exchange,提问作者user1823664
相关产品推荐
相关产品推荐

