免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: luoops
打印 上一主题 下一主题

[C] 关于函数入参顺序 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2013-05-06 21:13 |只看该作者
谢谢,明白了为什么是9 9 9!回复 2# 井蛙夏虫


   

论坛徽章:
4
白羊座
日期:2013-09-17 21:59:30技术图书徽章
日期:2013-10-12 22:16:03白羊座
日期:2013-10-14 11:01:40双子座
日期:2013-12-17 18:26:39
12 [报告]
发表于 2013-05-06 23:34 |只看该作者
回复 10# luoops
c语言的默认调用约定是规定了参数从右向左入栈,但入栈顺序不等于计算顺序。比如:
1. i -> eax; ++eax; eax -> i; i -> ebx; i -> ecx; --ecx; push ecx; push ebx; push eax;
2. i -> ecx; --ecx; ecx -> i; i -> ebx; i -> eax; ++eax; push ecx; push ebx; push eax;
上面两种情况入栈顺序都是从右向左,但计算顺序相反。
我刚用gcc和clang分别测试了你的例子(带volatile),gcc的计算顺序是从右向左,clang的计算顺序是从左向右。你可以测试一下。

你要观察不同调用约定下函数入参顺序,最好是用“gcc -S”或者“objdump -d”得到反汇编代码分析,或者gdb调试观察内存内容。

   

论坛徽章:
1
摩羯座
日期:2013-12-19 10:04:07
13 [报告]
发表于 2013-05-07 11:20 |只看该作者
回复 7# pmerofc

同意
   

论坛徽章:
1
摩羯座
日期:2013-12-19 10:04:07
14 [报告]
发表于 2013-05-07 11:25 |只看该作者
回复 10# luoops

入栈顺序 和 求值顺序 没什么联系的

对于你说的 从右向左入栈
可以是
从右向左全部求值完毕了 然后从右向左入栈
可以是
从左到右全部求值完毕了 然后从右向左入栈
可以说
随机高兴对那个求值就对那个求值 然后从右向左入栈
可以是从右边求值一个 就入栈一个
bbabababababababbababa........................................................

全废话
就一句 求值顺序不做保证 爱咋地咋地 入栈顺序和求值顺序不是一回事

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
15 [报告]
发表于 2013-05-07 13:39 |只看该作者
luoops 发表于 2013-05-03 17:32
无意中在网上看到一个问题:
int i = 9;
printf("%d %d %d\n", ++i, i, --i);

没必要研究这个问题,实际上,你如果不想你的程序一塌糊涂,就别这么用。

论坛徽章:
0
16 [报告]
发表于 2013-05-08 08:56 |只看该作者
如果是参数是函数呢?
比如func(func1(), func2());
func1和func2执行顺序也是不确定么?
回复 14# lin5161678


   

论坛徽章:
1
双子座
日期:2014-04-20 13:05:34
17 [报告]
发表于 2013-05-08 09:32 |只看该作者
反汇编一下

论坛徽章:
0
18 [报告]
发表于 2013-05-08 09:43 |只看该作者
这个的确是未定义行为,不同的编译器可能处理结果是不一样的,非要了解哪种编译器的结果是为什么,看反汇编加上举例测试,可以得出一些结论(注意不要仅以这一个例子去得出结论,因为通常这样得出的结论很可能是片面的)

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
19 [报告]
发表于 2013-05-08 09:56 |只看该作者
luoops 发表于 2013-05-08 08:56
如果是参数是函数呢?
比如func(func1(), func2());
func1和func2执行顺序也是不确定么?



参数是函数的话有两种情况:
1、传入参数用的是函数的返回值,这个相当于用表达式作为函数入参,求值顺序是编译器决定的,一般情况下没固定顺序,不要依赖
2、传入参数是个函数指针,这个近似于函数内嵌套函数(函数嵌套不是C语言,我这里借用FORTRAN的概念),除非你知道函数如何实现,否则也无法判定调用顺序

总之,编程要尽量弱化顺序依赖,特别是在现代CPU和编译器体系上,某些编译器在多CPU在环境下的某些行为可以用疯狂来形容

论坛徽章:
1
摩羯座
日期:2013-12-19 10:04:07
20 [报告]
发表于 2013-05-08 10:49 |只看该作者
回复 16# luoops

是的 对于 func(func1(), func2());
这里是先调用func1函数 还是先调用 func2函数
是无法确定的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP