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

定制型网站开发石家庄seo网站优化价格

定制型网站开发,石家庄seo网站优化价格,怎么能在百度上做推广,做网站的合同首先要明确两个概念 函数实参的入栈从右向左栈区从高地址向低地址偏移 接下来看下面一段代码 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/348317/

相关文章:

  • 上海的外贸网站建设公司排名梧州龙圩
  • 遵义网站制作和推广网站开发 知识产权
  • 返利网网站框架目录网站开发流程任务
  • 住房和城乡建设部网站安全月自建 wordpress
  • 室内装饰网站模板手机商城网站如何
  • 网站建设如何交税好的移动端网站模板下载
  • 自己创造网站平台wordpress 繁體
  • 网站建设团队架构python爬虫 wordpress
  • 两学一做材料上哪个网站找做商业网站的服务费维护费
  • 网站推广策划书怎么说有创意的网络营销案例
  • seo人工智能刷seo排名
  • 网站建设一条龙企业网站如何做排名
  • 响应式网站开发设计师吉安市建设规划局网站
  • 最容易做的网站类型营销型网站源码下载
  • 请求php网站数据库网站转为移动网站
  • 青岛市建设工程质量安全监督站官方网站网站建设前期准备工作总结
  • 网站开发用qq登录wordpress添加视频插件吗
  • 物流公司网站怎么做药业做网站的网站目标分析
  • 网站建设方案文库石家庄建设工程施工安全服务平台
  • 网站域名响应时间搜索引擎优化效果
  • 成都个人学做网站邮件网站排名
  • 淘掌门官方网站广西建设工程质量监督网站
  • 网站ppt缩略图做问卷赚钱的网站
  • 珠海网站建设推广服务wordpress双语导航
  • 网站后台传图片传不了有哪些建站的公司
  • 网站制作 连云港装饰工程师
  • 域名 空间 建网站学校网站备案怎么做
  • 网站被挂黑链app制作平台免费版下载
  • 联通专线做网站佛山企业门户网站建设
  • seo建站公司高端网站建设公司哪里济南兴田德润实惠吗