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

news2025/1/12 0:51:47

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.coloradmin.cn/o/1854435.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙开发系统基础能力:【@ohos.hiAppEvent (应用打点)】

应用打点 本模块提供了应用事件打点能力&#xff0c;包括对打点数据的落盘&#xff0c;以及对打点功能的管理配置。 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import hiAppEve…

英伟达下一代DLSS或利用人工智能

英伟达的黄仁勋在2024年Computex展会上的问答环节中&#xff0c;提前透露了公司未来几代深度学习超采样&#xff08;DLSS&#xff09;技术的发展方向。在回答有关DLSS的问题时&#xff0c;黄仁勋表示&#xff0c;未来我们将看到通过纯粹的人工智能生成的纹理和对象。他还提到&a…

通过ESP32读取I2C温湿度传感器项目:协议与代码实例

简介 在本项目中&#xff0c;我们将使用ESP32开发板读取I2C温湿度传感器的数据。我们将详细介绍I2C协议&#xff0c;并提供图文并茂的代码实例&#xff0c;帮助你快速上手。 项目流程 选择硬件&#xff1a;ESP32开发板、I2C温湿度传感器&#xff08;如DHT12、HTU21D、SHT30等&a…

yii2 ActiveForm使用技巧

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

虚拟现实环境下的远程教育和智能评估系统(十三)

管理/教师端前端工作汇总education-admin&#xff1a; 首先是登录注册页面的展示 管理员 首页 管理员登录后的首页如下图所示 管理员拥有所有的权限 课程管理 1、可以查看、修改、增添、删除课程列表内容 2、可以对课程资源进行操作 3、可以对课程的类别信息进行管理&…

【嵌入式开发】STM32+USB的快速开发

目录 一、概述 二、STM32+USB开发流程 2.1 建立新的工程 2.2 系统配置 2.3 时钟配置 2.4 操作系统 2.5 选择USB配置 2.6 在USB_HOST中选择支持的子类(class) 2.7 Clock 配置 三、注意事项 3.1 应用驱动配置 3.2 上电调试基础工作 一、概述 USB作为大家耳熟能详的…

Spdlog日志库的安装配置与源码解析(Linux)

为什么使用日志库而不是控制台输出&#xff1f; 日志库通常提供了更丰富的功能&#xff0c;比如可以设置日志输出级别、输出到不同的目标&#xff08;比如控制台、文件、网络等&#xff09;&#xff0c;以及格式化输出等。 使用日志库可以使代码更易于维护。通过统一的日志接口…

【web2】jquary,bootstrap,vue

文章目录 1.jquary&#xff1a;选择器1.1 jquery框架引入&#xff1a;$("mydiv") 当成id选择器1.2 jquery版本/对象&#xff1a;$(js对象) -> jquery对象1.3 jquery的页面加载事件&#xff1a;$ 想象成 window.onload 1.4 jquery的基本选择器&#xff1a;$()里内容…

计算机网络知识点汇总(三)

1.2 计算机网络体系结构与参考模型 1.2.1 计算机网络分层结构 计算机网络的各层及其协议的集合称为网络的体系结构(Architecture)。换言之&#xff0c;计算机网络的体系结构就是这个计算机网络及其所应完成的功能的精确定义。要强调的是&#xff0c;这些功能究竟是用何种硬件…

探索FlowUs息流:个人和团队知识管理稳定解决方案|FlowUs稳定保障你的笔记安全无忧

FlowUs息流&#xff1a;稳定运营保障你的笔记安全无忧 在知识管理工具的选择上&#xff0c;稳定性是用户最关心的问题之一。FlowUs息流以其稳定的运营记录&#xff0c;为用户提供了一个可靠的工作环境。我们深知&#xff0c;一个知识管理平台的稳定性直接影响到团队的生产力和…

阿里云推出首个 AI 程序员!

AI圈最近又发生了啥新鲜事&#xff1f; 该栏目以周更频率总结国内外前沿AI动态&#xff0c;是快速了解AI发展趋势一个不错的方式&#xff0c;感兴趣的可以点击订阅合集以及时收到最新推送 DeepSeek Coder V2开源发布&#xff0c;首超GPT4-Turbo的代码能力 全球首个在代码、数…

告别繁琐邀请码,Xinstall助你轻松搭建高效App推广体系!

随着互联网流量的不断变迁&#xff0c;App推广和运营面临着前所未有的挑战。如何快速搭建起满足用户需求的运营体系&#xff0c;成为众多企业亟待解决的问题。在这个背景下&#xff0c;Xinstall凭借其强大的功能和灵活的解决方案&#xff0c;成为了App推广的得力助手。 一、传…

【IVIF】Equivariant Multi-Modality Image Fusion

2024CVPR Zixiang Zhao团队 分析透彻&#xff0c;方法耳目一新 统一融合架构 1、Motivation Our approach is rooted in the prior knowledge that natural imaging responses are equivariant to certain transformations 我们的方法根植于自然成像响应对于某些变换的等变性…

线程C++

#include <thread> #include <chrono> #include <cmath> #include <mutex> #include <iostream> using namespace std;mutex mtx; void threadCommunicat() {int ans 0;while (ans<3){mtx.lock();//上锁cout << "ans" <…

MongoDB数据库的安装和删除

MongoDB数据库的删除和安装 1、删除MongoDB数据库2、下载MongoDB数据库1)、自定义安装2)、注意可视化可以取消勾选 1、删除MongoDB数据库 没有下载过的&#xff0c;可以直接跳到下面的安装过程↓ 我们电脑中如果有下载过MongoDB数据库&#xff0c;要更换版本的话&#xff0c;其…

opencascade AIS_InteractiveContext源码学习5 immediate mode rendering 即时模式渲染

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是&#xff0c;对于已经被交互上下文识别的交互对象&#xff0c;必须使用上下文方法进行…

安卓中使用ttf字体文件

官方文档中提供的方法要设备能访问google&#xff1f; 官方方法 直接下载字体的fft文件 我要使用的是lexend 需要的格式可以在里面搜索 使用下载的ttf文件 解压出来 可以单独使用static里面的&#xff0c;里面是直接的lexend的各种格式 但是我这里直接使用Lexend-Vari…

塞贝壳效应

塞贝克效应&#xff08;Seebeck effect&#xff09;&#xff0c;通常被称为第一热电效应&#xff0c;是由托马斯约翰塞贝克&#xff08;Thomas Johann Seebeck&#xff09;在1821年发现的一种热电现象。这个效应描述了当两种不同的导体或半导体在它们的接点处有温度差时&#x…

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

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

路经总和-二叉树题

112. 路径总和 - 力扣&#xff08;LeetCode&#xff09; 1、用队列 两个队列&#xff0c;先进先出 node队列存节点&#xff1b; sum队列存每条路径走到这个节点的val的总和&#xff1b; 节点和总和对应着同时存入队列&#xff0c;同时出队列&#xff1b; class Solution …