当前位置: 首页 > news >正文

大连市网站推广公司网站可以叫做系统吗

大连市网站推广公司,网站可以叫做系统吗,新公司网站怎么做推广,安阳做网站优化首先要明确两个概念 函数实参的入栈从右向左栈区从高地址向低地址偏移 接下来看下面一段代码 void fun(int a,int b,int c){std::cout<<&a<<" "<<&b<<" "<<&c<<std::endl; } int main(){fun(1,2,3); }…

首先要明确两个概念

  • 函数实参的入栈从右向左
  • 栈区从高地址向低地址偏移

接下来看下面一段代码

void fun(int a,int b,int c){std::cout<<&a<<" "<<&b<<" "<<&c<<std::endl;
}
int main(){fun(1,2,3);
}

这段代码看起来很简单但是你在不同环节下运行起来可能就会有问题了windows下vs
在这里插入图片描述
linux下vscode
在这里插入图片描述
可以看出一个是从左向右递增,一个是从左向右递减,你觉得这个是为什么呢?

我也不卖关子了,出现这种情况的原因是不同编译器将帧地址传递给函数后对函数局部变量的处理顺序不同。

函数从调用开始到结束过程

创建栈帧

在编译期编译器会根据类中局部变量的使用情况确定栈帧的大小

主函数帧指针
主函数内局部变量
返回地址
函数的帧指针(指向主函数帧指针)
函数的局部变量
栈指针

以上就是一个主函数调用一个函数时栈内的情况,栈帧可以理解为一个函数的活动空间,或者说运行环境,下面简述几个概念。

  • 帧指针:函数的主心骨,局部变量的创建都是在它的地址基础上偏移,它内部存函数调用者的帧指针地址
  • 栈指针,就是栈顶
  • 返回地址,存储调用函数完成后需要返回到的下一条指令的地址

栈帧的大小是在编译期间确定的,形参也处于局部变量的范畴,将实参从调用者的栈帧内移动到被调用者的栈帧内就涉及到了几种传参方式

  • 值传递
  • 址传递
  • 引用传递(也是通过址传递)

栈帧和代码区函数的交互

函数的运行在代码区,平时看汇编的时候如果你注意就会发现发生函数调用时一定会传一个东西,这个东西就是帧指针,比如下面这一坨

#include<iostream>
using namespace std;
void fun(){int nums[1024];
}int main() {fun();
}
fun():push    rbpmov     rbp, rspsub     rsp, 3976nopleaveret
main:push    rbpmov     rbp, rspcall    fun()mov     eax, 0pop     rbpret

这个rbp寄存器里面存的就是这个帧指针,sub rsp, 3976这个条指令就是进行栈指针的偏移,这个3976是栈帧内为局部变量预留的空间,至此可以说栈帧的创建完成了,接下来该使用了,局部变量的创建可以看到都是通过在rbp的基础上进行偏移的,需要注意的是编译器会进行各种优化你需要编译时加上-0o关闭优化,还有就是栈的对齐方式是16字节。

所以说当面试官问你栈区有没有产生内存碎片的可能时,你可以从容的回答栈的对齐大多数采用的是16字节可能会因为对齐方式而产生比较多的内存碎片,这些碎片显然是用不了的,高性能的代价往往是高内存消耗。

返回值的处理

一般来说对于返回值是函数的调用者需要关注的东西,现在的大部分编译器返回值的传递其实都是通过寄存器完成的,在不进行各种优化的情况下编译器会根据返回值的数据进行选择,如果数据量较大就使用寄存器返回地址,如果数据量较小则直接使用寄存器将结果返回,寄存器返回后会调用者的栈帧内拷贝一份函数的返回值,这个过程发生在函数栈帧被释放前,这个过程结合我之前的一篇文章:C++:完美转发和移动语义看会比较清楚。
上面那个过程显然不太合理,首先返回值不是被调用者需要考虑的东西,如果说我们直接在函数调用前在调用者的栈帧内创建好被调用者的返回值然后使用寄存器将这个地址传过去,在这个地址的基础上函数再进行处理不就行了吗?实际上这个就是RVO优化的原理,此外RVO还会判断返回值有没有被用到,如果没用的话也是会优化掉的。

RVO发生的条件通常是:在函数中创建了一个局部对象,并将其作为函数返回值,而调用方直接使用了这个返回值。在这种情况下,编译器可以直接将该局部对象放置到调用方期望的位置,而不需要进行复制或移动操作。

RVO失效情景

  • 返回多个对象: 如果函数返回多个对象,而不是一个单独的临时对象,那么RVO优化可能不适用。RVO通常仅适用于返回单个对象的情况
return pair<pair<int,int>,pair<int,int>>();
  • 虚函数调用: 当函数是虚函数时,编译器可能无法确定函数返回的对象的确切类型,从而阻止了RVO优化的应用
struct A{virtual A fun(){return *this;}};
struct B:public A{virtual B* fun(){return *this;}};
A* b=new B;
b->fun();
  • 复杂的返回逻辑
if(a) return a;
else if(b) return b;
return c;

观测RVO优化的过程,直接从上下文地址的变化非常直观

A get(){A a;cout<<&a<<endl;return a;
}int main() {A a;cout<<&a<<endl;a=get();A b;cout<<&b<<endl;
}

在这里插入图片描述
可以看到当发生RVO优化时会在调用者的栈帧内临时申请一块空间,生命周期过了就被下一个变量覆盖了,现在你应该对RVO和临时对象有了新的认识

总的来说,移动语义的引入可以说从根源上缓解了临时对象对程序性能的影响,就业务中可能出现的各种情况编译器可能不能很好的进行各种优化,所以合适的代码书写还是很有必要的,不要寄希望于各种优化了

栈帧的释放

返回值处理完成后,首先帧指针跳转到上一个节点然后栈指针向高地址偏移,直到遇到返回地址程序接着运行

回归到开头时候的问题,现在你大概已经直到答案了,没错就是不同操作系统在不同编译器下函数对参数的处理顺序不同造成的。

http://www.yayakq.cn/news/802871/

相关文章:

  • 婚恋网站 模板学好网页设计与网站建设的意义
  • 免费创建网站的软件微商城开发报价
  • 钓鱼转转网站在线生成软件免费试用网站源码
  • 网站建设工作进度温州广厦网页制作
  • 网站建设辶首先金手指十五wordpress 扫描
  • 建设制作外贸网站的公司wordpress怎么去掉顶栏
  • 江苏集团网站建设农业建设管理信息网站
  • 天津网站运营如何设计出一个好网站
  • 外国人搞笑做视频网站天眼查 公司查询企业查询官网
  • 太原网站排名以客为尊wordpress导入链接生成文章
  • wordpress网站相册腾讯云ADM怎么做网站
  • 大气的企业网站源码网站建设的目录浏览
  • 中山营销型网站网站自己做
  • 官方建网站哪个好优质的聊城做网站
  • ppt代做网站东莞市网站建设哪家好
  • 深圳外贸seo网站推广内在空间官网
  • 太子河网站建设wordpress博客联盟
  • 寻找客户资源的网站企业网站栏目设置说明
  • 扬中网站建设开发长兴住房和城乡建设局网站
  • 做电台需要的文章从哪个网站找个人网站建站系统
  • 陇西网站建设公司世界企业排名500强
  • 购物网站类型艺术签名设计免费版
  • 上海做网站静态网页有哪些网站
  • 电子商务网站建设实训室简介wordpress锚点
  • 网站系统正在升级维护网络推广主要是做什么工作
  • 做图书馆网站wordpress 插件发文章
  • 嘉兴做网站的上海网站建设推
  • 移动路由器做网站服务器吗惠州seo推广外包
  • 做个进出口英文网站多少钱开发小程序定制软件
  • 天津和平做网站哪家好做商城网站的公司推荐