a++与++a,谈谈C++的参数传递
2019-10-08 08:46:46来源:博客园 阅读 ()
a++与++a,谈谈C++的参数传递
先看一段代码:
#include<iostream>
using namespace std;
void func(int a, int b)
{
cout << a << " " << b << endl;
}
int main()
{
int a = 0;
func(a++, ++a);
return 0;
}
由于C++是从右向左入栈(与编译器的调用约定有关,不是C++标准的规定),所以刚看到代码的时候,我以为结果会是“1 1”(先将++a入栈,再将a++入栈),然而事实是: 。这是在VS上面运行的,在g++上也是一样的结果。幸好VS还可以查看汇编代码。
由于在VS上有十分方便的反汇编工具,所以接下来说的东西都基于VS2019自带的反汇编。
设置断点并调试,便可以打开反汇编窗口:
下面这段就是在调用func函数时的汇编代码:
mov eax,dword ptr [a]
add eax,1
mov dword ptr [a],eax //这三行指令将a+1
mov ecx,dword ptr [a]
mov dword ptr [ebp-0D0h],ecx //这两行指令将a的值存储到一个临时地址(寄存器间接寻址)中
mov edx,dword ptr [a]
add edx,1
mov dword ptr [a],edx /这三行指令又将a+1
mov eax,dword ptr [a]
push eax //这两行指令将a压入栈
mov ecx,dword ptr [ebp-0D0h]
push ecx //这两行指令将刚刚存储的临时地址的值压入栈
call func (0A312E9h) //调用func函数
add esp,8 //esp为栈指针寄存器
如果将代码改成
func(++a, ++a);
会是什么结果呢?答案是
mov eax,dword ptr [a]
add eax,1
mov dword ptr [a],eax //这三行指令将a+1
mov ecx,dword ptr [a]
add ecx,1
mov dword ptr [a],ecx //这三行指令将a+1
mov edx,dword ptr [a]
push edx //这两行指令将a压入栈
mov eax,dword ptr [a]
push eax //这两行指令将a压入栈
call func (09912E9h)
add esp,8
可以看到,将a++改成++a之后,指令少了将a的值保存起来的步骤,并且由于并非在读取参数时就压入栈,而是在所有参数的表达式执行完之后才压入,所以最后压入参数栈的都是最后的变量a。
那么结合汇编代码就不难理解文章开头为什么是“1 2”了,基本就是这样的区别(注意:读取参数和执行参数的表达式时也是从右往左的):
在调用函数的时候,参数要避免使用自增和自减,避免出现混乱。
文章为作者结合个人理解编写,可能会有错漏的地方,如有错误,敬请指正。
原文链接:https://www.cnblogs.com/fancyxie/p/11618369.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:树-基本概念,遍历,表示法
- 谈谈网络编程里的那些事 2018-06-18
- 我也要谈谈大型网站架构之系列(3)——死了都要说的缓存 2018-06-18
- 我也要谈谈大型网站架构之系列(4)——分布式中的异步通信 2018-06-18
- Nancy之静态文件处理 2018-06-18
- 一起谈谈MD5加密算法 2018-06-18
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash