首页 > 编程语言 >c/c++参数入栈顺序和参数计算顺序

c/c++参数入栈顺序和参数计算顺序

时间:2023-08-16 14:45:18浏览次数:40  
标签:顺序 入栈 c++ 函数参数 编译器 参数

如果大家细心的话应该知道c/c++语言函数参数入栈顺序为从右至左,那么为什么这样呢?来看看两个知识点:参数的计算顺序与压栈顺序。

参数入栈顺序

c/c++中规定了函数参数的压栈顺序是从右至左,函数调用协议会影响函数参数的入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。

参数传递和命名约定

Visual C/C++ 编译器支持以下调用约定。

 

官方详解可见:

https://msdn.microsoft.com/en-us/library/984x0h58(v=vs.120).aspx

通常情况下c/c++默认入栈方式:__cdel,也就是以右到左将参数压入堆栈,Windows api使用的是__stdcall方式,__fastcall适用于对性能要求较高的场合。

自定义参数入栈形式

当然我们也可以自定义函数的入栈顺序,常用形式如下

为什么要从右往左入栈?

每个参数都有自己的地址,但不定长参数无法确认地址,并且函数参数的个数也不确定,C/C++中规定了函数参数的压栈顺序是从右至左,对于含有不定参数的printf函数,其原型是printf(const char* format,…);其中format确定了printf的参数(通过format的%个数判断)。

假设是从左至右压栈,那么先入栈的是format,然后依次入栈未知参数,此时想要知道参数个数,就必须找到format,而要找到format,就必须知道参数个数,这样就会陷入一个死胡同里面了。

而c/c++中规定参数压栈为从右至左的顺序,这种方式对于不定参数,最后入栈的是参数个数,只需要取栈顶就可以得到。

我们举一个了例子如下:

 输出结果如下:

我们知道先入栈的占高地址,从结果看出入栈的顺序依次为z->y->x,即压栈顺序从右至左。

参数计算顺序

先执行哪个参数和参数的计算顺序有关,而c/c++中没有规定函数参数的计算顺序,这个和编译器有关,代码参数的计算顺序决定了实际输出。

vs的计算顺序是从右至左,clang的计算顺序是从左至右,具体的计算流程分析就很简单了。

对于c/c++函数参数的读取顺序,参数入栈时顺序从右向左入栈,但是在入栈前会先把参数列表里的表达式从右向左算一遍得到表达式的结果,最后再把这些运算结果统一入栈。

在参数入栈前,编译器会先把参数的表达式都处理掉,对于一般的操作来说,参数入栈时取值是直接从变量的内存地址里取的,但是对于a++操作,编译器会开辟一个缓冲区来保存当前a的值,然后再对a继续操作,最后参数入栈时的取值是从缓冲区取,而不是直接从a的内存地址里取。

结论

因为函数参数的计算顺序依照编译器的实现,所以在编码中避免编写诸如 fun(++x, x+y)这种的程序,其在不同的平台得到的结果可能不一样,但是在面试中可能遇到这样的问题,所以我们需要知其然更要知所以然。

>>>>>>>>转载 c/c++参数入栈顺序和参数计算顺序 (qq.com)

 

标签:顺序,入栈,c++,函数参数,编译器,参数
From: https://www.cnblogs.com/Zhaolongtao/p/17633979.html

相关文章

  • 1.C++入门以及简单顺序结构
    C++入门以及简单顺序结构一.编写一个简单的C++程序#include<iostream>usingnamespacestd;intmain(){ return0;}二.基础语法变量1.变量的概念变量本质上是一个装东西的盒子,并且只能存放一个值。2.变量的定义变量必须先定义,才可以使用inta=5;3.变量......
  • i513400f参数 i5 13400f性能怎么样酷睿i5 13400f属于什么水平
    i5-13400f7nm工艺采用拥有6个大核和4个小核,共计10核16线程,主频2.5GHz,全核睿频可达4.4GHz,单核睿频4.6GHz,配备28MB的L3缓存,基础功耗65W。i513400f组装电脑怎么搭配更合适这些点很重要 http://www.adiannao.cn/du ......
  • i7 13700k核显性能 酷睿i713700k参数 i7 13700k功耗
    酷睿i7-13700K核心代号为RaptorLake,采用的是增强版的Intel7工艺(10纳米),不锁频设计,采用了全新的高性能混合架构,由8个性能核+8个能效核构成,最终规格为16核心24线程,其中性能核(P核)采用的是RaptorLake架构,基本频率为3.4Ghz,最高睿频可至5.4GHz,而能效核(E核)延续了Gracemot架构设计,单E......
  • 通过命令行参数启动的后门病毒
    在恶意代码分析过程中,关注的重点是恶意代码的整体行为机制和运行逻辑,但是现在由于我们对底层实现逻辑还不太清楚所以花费了大量的时间在具体实现上,要在积累的前提下大胆猜测小心求证。今天我们换一种分析方式,先通过基础静态分析大致猜测恶意代码行为然后再具体分析具体的实现机制......
  • ChatGPT 问答00019 在Disruptor中,EventHandler的onEvent方法的3个参数分别代表什么
    在Disruptor中,EventHandler的onEvent方法的三个参数分别代表以下内容:event:表示当前处理的事件对象。它是从RingBuffer中获取的事件,你可以通过event对象访问和处理事件所携带的数据。sequence:表示当前事件的序号。每个事件在RingBuffer中都有一个唯一的序号,用于标识事件的......
  • R语言进行支持向量机回归SVR和网格搜索超参数优化|附代码数据
    全文链接:http://tecdat.cn/?p=23305最近我们被客户要求撰写关于支持向量机回归的研究报告,包括一些图形和统计输出。在这篇文章中,我将展示如何使用R语言来进行支持向量回归SVR我们将首先做一个简单的线性回归,然后转向支持向量回归,这样你就可以看到两者在相同数据下的表现。一个......
  • MT6765|MTK6765核心板,联发科Helio P35安卓核心板参数
    MT6765核心板采用基于MT6765八核处理器(4×A532.3GHz+4×A531.8GHz)的4G全网通模块,使用12nmFinFET制程工艺。该处理器内置安卓9.0操作系统,同时MTK6765提供LPDDR3或LPDDR4x内存的弹性选择。与上一代处理器相比,它的功耗降低了20%,性能提升了25%,使得产品开发商能够根据市场需求开发兼......
  • Mysqldump参数大全
    --all-databases,-A导出全部数据库。mysqldump-uroot-p--all-databases--all-tablespaces,-Y导出全部表空间。mysqldump-uroot-p--all-databases--all-tablespaces--no-tablespaces,-y不导出任何表空间信息。mysqldump-uroot-p--all-databases--no-tablespaces--a......
  • 模型超参数基本都没改,测试时加载模型报模型结构不匹配,设置模糊加载模型即:model.load_s
    原因多卡训练;单卡模糊加载进行测试。训练时,通过torch.nn.DataParallel(self.model)进行多卡并行训练;测试时,用单卡模糊加载保存的模型权重,很多模型参数都没有加载成功,自然会导致测试效果很差。解决方法测试时,使用多卡加载模型时,删掉'module.'前缀;或者用单卡加载模型进行测试。......
  • RabbitMQ如何保证顺序消费
    面试官:你能说说RabbitMQ是如何保证消息顺序消费的吗?老任:如果我们想要保证消息是按照顺序进行发送的,发送到队列后,队列的消息应该是先进先出的,我们只需要一个队列配置一个消费者即可(窃喜中......)。面试官:我们的项目一般都是集群部署的,一个队列就会有多个消费者,怎么实现一个队列中所......