社区
C语言
帖子详情
关于C语言的自动参数提升(default argument promotion)规则
out4b
2003-08-04 05:47:47
我在网上翻了一下,不太满意。
有没有人能讲清楚:
1. 除了在va_arg()中提取参数时可能用到外,这个default argument promotion规则什么时候会被用到?
2. 这个问题的来源是什么?为什么需要这条规则?
3. 它的精确定义到底是什么?
4. 在这问题上K&R C和ANSI C有没有区别?是什么区别?
谢谢。
...全文
290
16
打赏
收藏
关于C语言的自动参数提升(default argument promotion)规则
我在网上翻了一下,不太满意。 有没有人能讲清楚: 1. 除了在va_arg()中提取参数时可能用到外,这个default argument promotion规则什么时候会被用到? 2. 这个问题的来源是什么?为什么需要这条规则? 3. 它的精确定义到底是什么? 4. 在这问题上K&R C和ANSI C有没有区别?是什么区别? 谢谢。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
16 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
out4b
2003-08-05
打赏
举报
回复
补充:刚才试了一下,对于:
PrintMsg("%c %d %f\n", 1, 2, 3);
的确全是以int(4字节)压栈的。而对于:
PrintMsg("%c %d %f\n", a, b, c);
其中a, b, c分别为char, int float类型的参数,
a和b分别以4字节压栈, c以float压栈(8字节)。
试验环境为32bit x86, FreeBSD/gcc2.95.3
Riversking(纸风筝) :
可否详细讲讲?
fierygnu
2003-08-05
打赏
举报
回复
1、是我写例子时懒了一下,写成f(int(1))就是了。这是我的本意。
2、变参中的参数...是**总是**以提升后的类型压栈的。你的PrintMsg("%c %d %f\n", 1, 2, 3);调用会出问题,PrintMsg("%c %d %f\n", 1, 2, 3.0);就不会出问题了。这个不是编译器的职责,是程序员的职责。这就是使用可变参数列表的危险所在。
3、va_arg()在运行时是根据你编程时指定的类型提取3这个参数的。
Riversking
2003-08-05
打赏
举报
回复
c程序设计有详细说明。清华的。谭老写的。
out4b
2003-08-05
打赏
举报
回复
fierygnu(va_list):
我觉得你说的算术运算和第3点中的f(1)和这个va_arg()中遇到的default argument promotion规则还是有不同之处的。
算术运算以及调用f(1)时我认为不能算是一个default argument promotion, 常量的类型是在编译时根据函数原型指定好了的,这里并没有发生提升的情况。(仅仅是完成一次语义上的转化,一般的编译原理书上都有讲)
而用va_arg(arg, type)提取参数时,va_arg()事先并不知道以什么类型提取(因为是以变参中的...表示的),所以在这种情况下,比如在格式中遇到一个%c,它仍然是以va_arg(arg, int)方式来提取这个char类型的参数,而这种情况和上面的f(1)我觉得是有区别的。这里的区别问题在于,变参中的参数...是不是**总是**以提升后的类型压栈的?比如说,考虑下面这个函数:
void PrintMsg(char *errMsg , ...);
对这个函数有以下的调用:
PrintMsg("%c %d %f\n", 1, 2, 3);
这里的三个参数3,2,1在调用者压栈时分别是以什么类型压进去的呢?是不是参数1和2都是以int方式压栈,而3用double方式压栈?我认为编译器无法解决这个问题,它如何知道3在压栈时应该使用double类型呢?而同样的,如果不能确定栈上的参数类型,va_arg()在运行时又如何知道应该用float/double类型提取3这个参数呢?
fierygnu
2003-08-05
打赏
举报
回复
主要的几个地方:
1、可变参数列表,即va_arg(),这个是规定,因为编译器不知道函数原型,更不知道你的函数内部要的是什么类型,所以定义了这个规则。
2、算术运算,这个是小的应用
3、函数参数匹配,比如声明了void f(double),你调用f(1)是可以的,就是这个规则在起作用;f("hello")不行,也是这个规则。
4、进一步的,函数参数匹配也用在C++的函数overloading里,这时就可能会引起二义性。
out4b
2003-08-05
打赏
举报
回复
Caoyu015(Cooyu(酷鱼一代)) :
算术运算时的自动类型提升肯定会发生的,你还提到一种情况是形参和实参转换时的自动提升是指什么呢?
我的问题是从va_arg()来的,这个宏在处理变参...的时候,对于所有char, short类型的参数
都以int类型提取,对于float类型的参数都以double类型提取。我不太清楚的是,这样做的依据何在?
out4b
2003-08-05
打赏
举报
回复
说实在的我还是有点迷惑,不过就这样吧,先把分给了再说。:)
fierygnu
2003-08-05
打赏
举报
回复
1、我用了C++的方式。
3、这样理解也行。
out4b
2003-08-05
打赏
举报
回复
fierygnu(va_list) :
1. 应该是f((int)1)吧?
2. sorry我写错了,编译器肯定知道3和3.0的区别。:)
3. 我是不是可以说,这个自动提升规则是不是*仅仅*在不清楚参数类型的情况(如变参)才会发生?
ckacka
2003-08-04
打赏
举报
回复
double的精度比float高
magic007
2003-08-04
打赏
举报
回复
C语言没仔细研究过,不过C++ 在c++ primer上讲得很清楚
Caoyu015
2003-08-04
打赏
举报
回复
很久没有温习以前的C语言基础部分了,如果有错误请见晾。:)
Caoyu015
2003-08-04
打赏
举报
回复
基本类型: char-> short-> int-> long-> double-> float .
在两个不同类型之间发生算术运算 如:
char ch = 'a';
float fs = 9.88;
fs = ch + fs; //运算时是直接的提升到float类型,而不是先提升到 short ->int -> long;
再到 float;
这种例子有很多。
out4b
2003-08-04
打赏
举报
回复
能否说详细一点?
Caoyu015
2003-08-04
打赏
举报
回复
参数提升一般发生在从实参到形参的转换和一般的算术运算之时。
提升的规则应该在教课书的前几页上就有。
out4b
2003-08-04
打赏
举报
回复
关注一下,不要跑到第二页去了。:)
C语言
的
自动
参数
提升
(
default
argument
pro
mot
ion
)
规则
1. 除了在va_arg()中提取
参数
时可能用到外,这个
default
argument
pro
mot
ion
规则
什么时候会被用到? 2. 这个问题的来源是什么?为什么需要这条
规则
? 3. 它的精确定义到底是什么? 4. 在这问题上K&R C和ANSI C...
c语言
关闭
自动
参数
提升
,
C语言
的
自动
参数
提升
(
default
argument
pro
mot
ion
)
规则
除了在va_arg()中提取
参数
时可能用到外,这个
default
argument
pro
mot
ion
规则
什么时候会被用到?2. 这个问题的来源是什么?为什么需要这条
规则
?3. 它的精确定义到底是什么?4. 在这问题上K&R C和ANSI C有没有...
c语言
默认
参数
提升
,
C语言
可变长
参数
函数与默认
参数
提升
1、概述C标准中有一个默认
参数
提升
(
default
argument
pro
mot
ion
s)
规则
。默认
参数
提升
有时会给我们带来疑惑。本文结合
C语言
的可变长
参数
函数来说明默认
参数
提升
存在的陷阱。2、默认
参数
提升
的定义标准中的定义如下:...
C语言
可变长
参数
函数与默认
参数
提升
学习本章内容的时候,...C标准中有一个默认
参数
提升
(
default
argument
pro
mot
ion
s)
规则
。 默认
参数
提升
有时会给我们带来疑惑。本文结合
C语言
的可变长
参数
函数来说明默认
参数
提升
存在的陷阱。 2、默认
参数
提升
的...
C语言
可变长
参数
函数与默认
参数
提升
(转)
1、概述C标准中有一个默认
参数
提升
(
default
argument
pro
mot
ion
s)
规则
。 默认
参数
提升
有时会给我们带来疑惑。本文结合
C语言
的可变长
参数
函数来说明默认
参数
提升
存在的陷阱。2、默认
参数
提升
的定义标准中的定义...
C语言
69,372
社区成员
243,080
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章