免费注册 查看新帖 |

Chinaunix

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

[C] printf参数入栈顺序和编译器相关,还是都是从右至左? [复制链接]

论坛徽章:
0
41 [报告]
发表于 2007-11-01 11:57 |只看该作者
原帖由 JohnBull 于 2007-11-1 11:18 发表


是的,否则变参函数无法实现。

请给出个例子,为什么变参无法实现。

还是应用一些经典教材吧,见《C陷阱与缺陷》159、160页

1.JPG (31.33 KB, 下载次数: 66)

1.JPG

2.JPG (19.91 KB, 下载次数: 59)

2.JPG

论坛徽章:
0
42 [报告]
发表于 2007-11-01 12:01 |只看该作者
原帖由 思一克 于 2007-11-1 11:38 发表
这个问题应该是这样的:

在有些机器上,STACK是从低地址向高地址生长的, 为了保证ARG1到ARGN符合低-高的次序(变参,和一些库程序依赖该次序), 就要先入栈ARG1.

原来有一个贴, 争论这个问题,我一直以为永远是 ...

我不认为有这个依赖。
参数和局部变量在栈上分配空间其实是一至的。
例如gcc3中分配局部变量的顺序和定义顺序相同,但在gcc4中正好相反。这就说明了在栈上分配空间的顺序和栈的增长方向是无关的。
实际上,用mov来存取变量是不受分配空间顺序限制的。而c语言正是使用的mov,而非pop

论坛徽章:
0
43 [报告]
发表于 2007-11-01 12:07 |只看该作者
看这个贴. 我找到的. 注意,我的结论是错的,win-hate等的是对的.
也就是说,次序是变化的.

http://bbs.chinaunix.net/viewthr ... ;extra=&page=12

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
44 [报告]
发表于 2007-11-01 12:16 |只看该作者
原帖由 思一克 于 2007-11-1 12:07 发表
看这个贴. 我找到的. 注意,我的结论是错的,win-hate等的是对的.
也就是说,次序是变化的.

http://bbs.chinaunix.net/viewthread.php?tid=473288&extra=&page=12


好的,学习一把

论坛徽章:
0
45 [报告]
发表于 2007-11-01 12:19 |只看该作者
原帖由 zx_wing 于 2007-11-1 11:51 发表

大大哥,printf的参数个数是靠第一个参数那个字符串确定的。
printf无法检测出你错误的传入参数个数的,例如

printf("%d,%d,%d\n",1,2,3,4,5,6);

一样是正确的。

pop和mov当然有本质区别,如果用po ...

大大大哥,我现在清醒得很,你的一个问题在于:你怎么知道第一个参数的位置在哪里???
mov总得找到第一个参数的位置吧。
如果第一个参数总是第一个pop出来的,就不会有问题。

如果你能给出一个方法定位第一个参数的位置,你就说服我了

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
46 [报告]
发表于 2007-11-01 12:27 |只看该作者
原帖由 bluesky_jxc 于 2007-11-1 12:19 发表

大大大哥,我现在清醒得很,你的一个问题在于:你怎么知道第一个参数的位置在哪里???
mov总得找到第一个参数的位置吧。
如果第一个参数总是第一个pop出来的,就不会有问题。

如果你能给出一个方法定位 ...


前面不是有朋友提到,《C陷阱与缺陷》里提到参数的确定是按照那个格式字符串来的吗

论坛徽章:
0
47 [报告]
发表于 2007-11-01 12:35 |只看该作者
原帖由 bluesky_jxc 于 2007-11-1 12:19 发表

大大大哥,我现在清醒得很,你的一个问题在于:你怎么知道第一个参数的位置在哪里???
mov总得找到第一个参数的位置吧。
如果第一个参数总是第一个pop出来的,就不会有问题。

如果你能给出一个方法定位 ...

哈哈,这个确实是个问题。但你这样想是因为你把思维局限在了printf现在的原型上。
是因为有了从右向左的入栈顺序,才有printf现在的原型。
如果c语言的入栈顺序是从左向右,printf就会变成:

  1. printf(arg..., const char *fmt);
复制代码

是先有入栈顺序才有函数根据这种形式的实现,而不是为了函数的实现而特定某种入栈顺序。

论坛徽章:
0
48 [报告]
发表于 2007-11-01 12:40 |只看该作者
我认为现在大多数讨论都偏离方向了,变成了先有鸡还是先有蛋的问题。
思一克的帖子我也看了看,太长了,没有细看完,但认为还是一样的。都是讨论的是现在它是这个样子,然后转而讨论它为什么是这个样子,而实际上,我们应该看到除了现在这个样子,它还能不能实现成其它样子
我认为是可以的,我觉得不能看到了现在的实现,就认为它只能这样实现。就像以前讨论的linux中中断能不能睡眠一样,不能因为它实现是不能,就认为不能做到。实现是多样的,我们不能太局限了。

[ 本帖最后由 zx_wing 于 2007-11-1 12:44 编辑 ]

论坛徽章:
0
49 [报告]
发表于 2007-11-01 14:05 |只看该作者
原帖由 zx_wing 于 2007-11-1 12:35 发表

哈哈,这个确实是个问题。但你这样想是因为你把思维局限在了printf现在的原型上。
是因为有了从右向左的入栈顺序,才有printf现在的原型。
如果c语言的入栈顺序是从左向右,printf就会变成:

printf(arg ...

OK,既然大家都知道怎么回事,就不用纠缠在这一点上了。

我现在关心的是:为什么栈的生长方向和参数的入栈顺序有关?版主能描述一下么?

论坛徽章:
0
50 [报告]
发表于 2007-11-01 16:53 |只看该作者
错误.

从左到右, printf也不变.


原帖由 zx_wing 于 2007-11-1 12:35 发表

哈哈,这个确实是个问题。但你这样想是因为你把思维局限在了printf现在的原型上。
是因为有了从右向左的入栈顺序,才有printf现在的原型。
如果c语言的入栈顺序是从左向右,printf就会变成:

printf(arg ...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP