C++初学者指南第一步---14.函数调用机制

C++初学者指南第一步—14.函数调用机制

文章目录

  • C++初学者指南第一步---14.函数调用机制
    • 1.记住:内存的结构
    • 2.函数调用是如何工作的
    • 3. 不要引用局部变量
    • 4. 常见编译器优化
    • 5. Inlining内联

1.记住:内存的结构

在这里插入图片描述
堆(自由存储)

  • 用于动态存储期对象,例如 std::vector 的内容。
  • 空间大,可以用于大容量存储(大多数用于主内存)。
  • 可以根据需要分配和释放任何对象。
  • 按照无特定顺序的分配(释放) ⇒ 碎片化。
  • 分配速度慢:需要为新对象找到连续未被占用的空间。

在这里插入图片描述

  • 自动存储期对象使用:局部变量,函数参数等。
  • 空间小(通常只有几兆(M)字节)。
  • 分配速度快:新对象总是放在栈顶部。
  • 对象按它们创建的相反顺序被释放。
  • 无法释放顶端(= 最新的)以下的对象。

2.函数调用是如何工作的

<1>该示例假定没有编译器优化,例如内联(用函数体替换函数调用),返回类型优化等。
此外,在函数调用时放入栈的确切顺序(调用约定)取决于平台(CPU 架构 + 操作系统 + 编译器)。
在这里插入图片描述
<2>程序开始。
在这里插入图片描述
<3>局部变量 y 被放入栈。
在这里插入图片描述
<4> 局部变量 i 被放入栈。
在这里插入图片描述
<5> 函数的返回值占位符被放入堆栈
在这里插入图片描述
<6> 当前指令的内存地址被放在栈上,这样在离开被调用的函数后,我们就知道从哪里恢复程序。
在这里插入图片描述
<7> 帧指针标记了当前函数的栈帧的开始。在当前栈帧内的一切都将被视为函数局部的。需要帧指针是因为不同的函数调用可能有不同大小的栈帧。
在这里插入图片描述
<8> 执行跳转到函数square的内存地址。
在这里插入图片描述
<9> 函数参数p放在栈上,它的值由调用参数(y的值)决定。
注意:返回地址、占位符、局部参数等放在栈上的顺序取决于平台的调用约定(CPU体系结构+ OS +编译器)。
在这里插入图片描述
<10> 函数局部变量 x 放到栈上。
在这里插入图片描述
<11> 表达式 p * p 的结果被赋给 x。
在这里插入图片描述
<12> 语句return x,将 x 的值复制到 返回值占位符。
在这里插入图片描述
<13>离开函数square时: 堆栈的顶部位置减少到堆栈帧下方;这意味着所有函数局部变量都从堆栈中弹出。
在这里插入图片描述
<14> 执行通过跳转到之前存储的返回地址返回到调用位置。
在这里插入图片描述
<15> 赋值语句int i = …会导致返回值被复制到i中。
在这里插入图片描述
<16> square函数的返回值被从栈中弹出。
在这里插入图片描述
<17> 局部变量k被放入栈。
在这里插入图片描述
<18> 程序结束,所有关联的变量都会从栈中弹出。
在这里插入图片描述

3. 不要引用局部变量

如果我们把返回类型改为int&会怎么样呢?
<1>
在这里插入图片描述
<2> 在从square返回之前栈内容:

  • 函数局部变量x
  • 函数参数p
  • 函数调用后的下一条指令的地址
  • square返回值的占位符
  • main函数的局部变量 y 和 i
    在这里插入图片描述
    <3> 语句return x;将 x 的地址复制到 返回值占位符。
    在这里插入图片描述
    <4> 离开函数square: 栈的顶部位置降低到栈帧下方; 这意味着所有square函数的局部变量都会从栈中弹出。
    通过跳转到先前存储的返回地址,执行流程回到调用位置。
    在这里插入图片描述
    <5> 赋值 int& i = … 会导致返回值(一个整数的内存地址)被复制到引用 i& 中。
    x的内存位置实际上在栈的当前顶部位置之上。任何后续的栈分配都会导致它被其他值覆盖。
    这将导致 => 未定义行为
    这样的程序在运行时行为是未定义的/非确定性的,因为它有时可能会工作(如果 x 的内存没有被覆写)有时可能不会。
    在这里插入图片描述

4. 常见编译器优化

现代的 C++ 编译器进行多项优化(尤其是在较高的优化级别 -O2 和 -O3),使函数调用速度更快。
Return Value Optimization 返回值优化 (RVO)

  • 适用于类似:return Type{}; 或 return Type{argument,…}; 这样的语句。
  • 不会分配额外的占位符用于返回值,也不会进行复制。相反,外部对象 res 将直接在调用位置构造。
  • 这种优化是强制的,即在 C++17 版本中必定会执行。
Point foo (…) { 
  …
  return Point{…};
}
Point res = foo();

Named Return Value Optimization 命名返回值优化 (NRVO)

  • 适用于类似: return local_variable; 这样的语句。
  • 不会分配额外的占位符用于返回值,也不会进行复制。相反,本地对象 loc 和外部对象 res 被视为同一个对象。这样在调用点仅会发生一次分配。
  • 这种优化不是必需的,但几乎所有现代编译器都会尽可能地执行它。
Point foo (…) {
  Point loc;
  …
  return loc;
}
Point res = foo();

5. Inlining内联

调用小/短函数的地方被该函数的代码替换。
在这里插入图片描述
内联只会发生在编译器“看到”函数声明的同时也看到它的完整定义,如果我们分别编译程序的不同部分,这种情况就不一定会发生(更多内容请参考《分离编译》章节)。
这是 C++ 性能优势的一个来源。在许多其他语言(比如 Java、C# 等)中,内联化要困难得多,有时甚至是不可能的。这些语言通常具有始终开启的多态性,这意味着所有/大多数函数/方法调用只能在运行时解析。

附上原文链接
如果文章对您有用,请随手点个赞,谢谢!^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/736762.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Cesium如何高性能的实现上万条道路的流光穿梭效果

大家好&#xff0c;我是日拱一卒的攻城师不浪&#xff0c;专注可视化、数字孪生、前端、nodejs、AI学习、GIS等学习沉淀&#xff0c;这是2024年输出的第20/100篇文章&#xff1b; 前言 在智慧城市的项目中&#xff0c;经常会碰到这样一个需求&#xff1a;领导要求将全市的道路…

PADS学习笔记

1.PADS设计PCB流程 封装库&#xff08;layout&#xff09;&#xff0c;原理图库&#xff08;logic&#xff09;的准备原件封装的匹配&#xff08;logic&#xff09;原理图的绘制&#xff08;logic&#xff09;导网表操作&#xff08;logic&#xff09;导入结构&#xff08;lay…

SpringBoot + 虚拟线程,鸟枪换大炮!

“虚拟”线程&#xff0c;望文生义&#xff0c;它是“假”的&#xff0c;它不直接调度操作系统的线程&#xff0c;而是由JVM再提供一层线程的接口抽象&#xff0c;由普通线程调度&#xff0c;即一个普通的操作系统线程可以调度成千上万个虚拟线程。 虚拟线程比普通线程的消耗要…

Centos7安装自动化运维Ansible

自动化运维Devops-Ansible Ansible是新出现的自动化运维工具&#xff0c;基于Python 开发&#xff0c;集合了众多运维工具&#xff08;puppet 、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置 、批量程序部署、批量运行命令 等功能。Ansible…

Java8 --- Gradle7.4整合IDEA

目录 一、Gradle整合IDEA 1.1、Groovy安装 1.1.1、配置环境变量 ​编辑 1.2、创建项目 ​编辑 1.3、Groovy基本语法 1.3.1、基本语法 1.3.2、引号 1.3.3、语句结构 1.3.4、数据类型 1.3.5、集合操作 1.4、使用Gradle创建普通Java工程 1.5、使用Gradle创建Java ss…

JavaScript之类(1)

class基础语法结构&#xff1a; 代码&#xff1a; class MyClass {constructor() { ... }method1() { ... }method2() { ... }method3() { ... }... } 解释&#xff1a; 属性解释class是我们定义的类型(类)MyClass是我们定义的类的名称 constructor()我们可以在其中初始化对象m…

基于YOLOv5的PCB板缺陷检测系统的设计与实现(PyQT页面+YOLOv5模型+数据集)

简介 随着电子设备的广泛应用,PCB(印刷电路板)作为其核心部件,其质量和可靠性至关重要。然而,PCB生产过程中常常会出现各种缺陷,如鼠咬伤、开路、短路、杂散、伪铜等。这些缺陷可能导致设备故障,甚至引发严重的安全问题。为了提高PCB检测的效率和准确性,我们基于YOLOv…

2-14 基于matlab的GA优化算法优化车间调度问题

基于matlab的GA优化算法优化车间调度问题。n个工作在m个台机器上加工。已知每个工作中工序加工顺序、各工序的加工时间以及每个工件所包含的工序&#xff0c;在满足约束条件的前提下&#xff0c;目的是确定机器上各工件顺序&#xff0c;以保证某项性能指标最优。程序功能说明&a…

华为数通——单臂路由

单臂路由&#xff1a;指在三层设备路由器的一个接口上通过配置子接口&#xff08;或“逻辑接口”&#xff0c;并不存在真正物理接口&#xff09;的方式&#xff0c;实现原来相互隔离的不同VLAN&#xff08;虚拟局域网&#xff09;之间的互联互通。但是仅仅允许单播通信。 单臂路…

如何在Qt Designer中管理QSplitter

问题描述 当按下按钮时&#xff0c;我希望弹出一个对话框&#xff0c;用户可以在其中选择内容并最终按下 ‘Ok’ 按钮。我想在这个对话框中放置一个 QSplitter&#xff0c;左侧面板将显示树状结构&#xff0c;右侧将显示其他内容。如何正确实现这一点&#xff1f; 从 Qt 的示…

6.S081的Lab学习——Lab8: locks

文章目录 前言一、Memory allocator(moderate)提示&#xff1a;解析 二、Buffer cache(hard)解析&#xff1a; 三、Barrier (moderate)解析&#xff1a; 总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招。打算尝试6.S081&#xff0c;将它的Lab逐一实现&#xff0c;并…

番外篇 | 基于YOLOv5-RCS的明火烟雾检测 | 源于RCS-YOLO

前言:Hello大家好,我是小哥谈。RCS-YOLO是一种目标检测算法,它是基于YOLOv3算法的改进版本。通过查看RCS-YOLO的整体架构可知,其中包括RCS-OSA模块。RCS-OSA模块在模型中用于堆叠RCS模块,以确保特征的复用并加强不同层之间的信息流动。本文就给大家详细介绍如何将RCS-YOLO…

【原创】springboot+mysql海鲜商城设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

yii2 ActiveForm使用技巧

持续更新&#xff1a; 1、搜索输入框&#xff1a;form-inline <?php $form ActiveForm::begin([action > [index],method > get,options > [class > form-inline] &#xff08;增加此行代码&#xff09; ]); ?>

大型企业网络DHCP服务器配置安装实践@FreeBSD

企业需求 需要为企业里的机器配置一台DHCP服务器。因为光猫提供DHCP服务的能力很差&#xff0c;多机器dhcp多机器NAT拓扑方式机器一多就卡顿。使用一台路由器来进行子网络的dhcp和NAT服务&#xff0c;分担光猫负载&#xff0c;但是还有一部分机器需要放到光猫网络&#xff0c;…

本地离线模型搭建指南-中文大语言模型底座选择依据

搭建一个本地中文大语言模型&#xff08;LLM&#xff09;涉及多个关键步骤&#xff0c;从选择模型底座&#xff0c;到运行机器和框架&#xff0c;再到具体的架构实现和训练方式。以下是一个详细的指南&#xff0c;帮助你从零开始构建和运行一个中文大语言模型。 本地离线模型搭…

【网络安全的神秘世界】已解决burpsuite报错Failed to start proxy service on 127.0.0.1:8080

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 解决burpsuite无法在 127.0.0.1&#xff1a;8080 上启动代理服务端口被占用以及抓不到本地包的问题 Burpsuite无法启动proxy…

RabbitMQ(六)仲裁队列、流式队列、异地容灾(联邦队列Federation Queue)

文章目录 仲裁队列1、创建交换机2、创建仲裁队列3、验证主节点宕机不影响消息发送和接收 流式队列&#xff08;不推荐&#xff0c;Kafka主场&#xff09;概念 异地容灾一、Federation插件概述 二、Federation交换机1、总体说明2、准备工作3、启用联邦插件4、添加上游连接端点5、…

【Flink metric】Flink指标系统的系统性知识:以便我们实现特性化数据的指标监控与分析

文章目录 一. Registering metrics&#xff1a;向flink注册新自己的metrics1. 注册metrics2. Metric types:指标类型2.1. Counter2.2. Gauge2.3. Histogram(ing)4. Meter 二. Scope:指标作用域1. User Scope2. System Scope ing3. User Variables 三. Reporter ing四. System m…