关于返回结构体的函数

简介:     【前言】写作本文,源于最近回复的 《汇编中函数返回结构体的方法》 一文。在网络上也已经有一些相关文章和相关问题,有的文章已经给出了一部分结果,但总体而言还缺少比较重要的结论。本文以分析 VC6 编译器,32 位架构为主来重复性分析这个话题。

    【前言】写作本文,源于最近回复的 《汇编中函数返回结构体的方法》 一文。在网络上也已经有一些相关文章和相关问题,有的文章已经给出了一部分结果,但总体而言还缺少比较重要的结论。本文以分析 VC6 编译器,32 位架构为主来重复性分析这个话题。

 

    (一)不超过 8 bytes 的小结构体可以通过 EDX:EAX 返回。

    本文的范例代码取材于 《汇编中函数返回结构体的方法》一文,并在此基础上进行修改和试验。要研究的第一份代码如下,定义一个不超过 8 bytes 的小结构体,不超过 8 bytes 是因为这个结构体能够用 EDX:EAX 容纳,我们之后将看到在 release 编译时,编译器能够向返回普通基础类型那样进行返回。

 

#include <stdio.h>

//不超过 8 bytes 的“小结构体”
struct A
{
    int a;
    int b;
};

//返回结构体的函数
struct A add(int x, int y)
{
    struct A t;
    t.a = x * y;
    return t;
}

int main()
{
    struct A t = add(3, 4);
    printf("t.a = %ld\n", t.a);
    return 0;
}

 

    首先,我们需要解决一个常见困惑,就是要明确这段代码和下面的典型错误代码的区别:

    char* get_buffer()

    {

      char buf[8];

      return buf;

    }

    上面的 get_buffer 返回的是栈上的临时变量空间,在函数返回后,其所在的空间也就被“回收/释放”了,也就是说函数返回的地址位于栈的增长方向上,是不稳定和不被保证的。

    那么返回结构体的函数则不同,你可以发现返回结构体的函数是工作正常有效的。在 add 函数中有一个临时性结构体 t,毫无疑问,t 将在 add 函数返回时被释放,但由于 t 被当做“值”进行返回,因此编译器将保证 add 的返回值对于 add 的调用者(caller)来说是有效的。

 

    另外需要明确的一点是,我个人觉得,现实里这种返回结构体的方式比较少见,后面将会看到这样做会产生临时对象和多余拷贝过程,效率不高。常见方法是传递结构体指针。但作为语言上允许的方式,有必要弄清楚编译器如何实现这种方式,而要弄清楚这个问题,需要查看汇编代码。使用 VC6 输入上述代码,下面分别给出其汇编代码。

 

    (1)debug 版本,汇编代码如下。

 

small_struct_debug
.text:00401020 add             proc near               ; CODE XREF: j_add
目录
相关文章
|
5月前
|
SQL 人工智能 API
一个人干五个人的活?Copilot CLI 的 `/fleet` 让你体验“影分身术“
GitHub Copilot CLI 新增 `/fleet` 命令,化身“AI包工头”,智能拆解需求、调度多子代理并行处理跨文件任务(如重构+测+文档),支持依赖编排与实时监工。提升开发效率,助你从执行者进阶为指挥官!
422 0
|
前端开发
css:flex布局最后一个子元素靠右摆放
css:flex布局最后一个子元素靠右摆放
1337 0
css:flex布局最后一个子元素靠右摆放
|
6月前
|
数据处理 开发者 SoC
【SOC估计】基于扩展卡尔曼滤波器的锂离子电池电荷状态计算附Matlab代码
【SOC估计】基于扩展卡尔曼滤波器的锂离子电池电荷状态计算附Matlab代码
350 11
|
10月前
|
人工智能 自然语言处理 机器人
中小企业也能玩转大模型:把AI搬到自己机房里不是梦
中小企业也能玩转大模型:把AI搬到自己机房里不是梦
2128 3
|
8月前
|
机器学习/深度学习 人工智能 运维
2026 AI 元年:唐宇昕:从大模型能力到工程化落地的关键转折
过去几年,大模型能力的提升有目共睹,但在真实业务环境中,一个越来越清晰的共识正在形成: 模型可用,并不等于系统可用,更不等于业务长期可用。 进入 2026 年,随着推理成本持续下降、模型能力逐步标准化,AI 的竞争焦点正在发生转移—— 从“谁的模型更强”,转向“谁能把 AI 稳定地跑在生产环境中”。 从这个意义上看,2026 年并不是模型能力爆发的一年,而是 AI 应用真正起飞的一年。
373 3
|
人工智能 自然语言处理 Nacos
Nacos 3.0:微服务与AI融合的全新治理平台
Nacos 3.0:微服务与AI融合的全新治理平台
472 46
|
Python
Python使用isinstance()函数
【5月更文挑战第10天】Python使用isinstance()函数
1290 2
|
Shell 测试技术 网络安全
【GIT】如何在GitHub上向一个开源项目贡献代码?
【GIT】如何在GitHub上向一个开源项目贡献代码?
629 5
|
Docker 容器
使用容器编排工具docker swarm安装clickhouse多机集群
1.首先需要安装docker最新版,docker 目前自带swarm容器编排工具 2.选中一台机器作为master,执行命令sudo docker  swarm init [options] 3,再需要加入集群的集群上执行此命令   4.
4871 0
|
存储 编译器
函数栈帧深度剖析(一篇带你牢牢掌握函数栈帧)(二)
函数栈帧深度剖析(一篇带你牢牢掌握函数栈帧)(二)
673 1

热门文章

最新文章