va_arg的一个问题,求解释

ken_scott 2013-04-30 04:49:50

#include <stdarg.h>
#include <cstdio>
#include <cassert>

void va_test(int ifirst, ...)
{
int ivalue = ifirst;
va_list va;

va_start(va, ifirst);

while (-1 != ivalue)
{
printf("%d ", ivalue);
ivalue = va_arg(va, int);
}
printf("\n");

va_end(va);
}

void va_test(float ffirst, ...)
{
float fvalue = ffirst;
va_list va;

va_start(va, ffirst);

while (-1.0000001f > fvalue || -0.9999999f < fvalue)
{
printf("%f ", fvalue);
fvalue = va_arg(va, float);
}
printf("\n");

va_end(va);
}

void va_test(double dfirst, ...)
{
double dvalue = dfirst;
va_list va;

va_start(va, dfirst);

while (-1.0000001 > dvalue || -0.9999999 < dvalue) // ignore it
{
printf("%f ", dvalue);
dvalue = va_arg(va, double);
}
printf("\n");

va_end(va);
}

int main(int argc, char * argv[])
{
assert(sizeof(int) == sizeof(float));
va_test(1, 2, 3, -1); // as we want
va_test(1.0, 2.0, 3.0, -1.0); // as we want
va_test(1.0f, 2.0f, 3.0f, -1.0f); // badly
return(0);
}


如注释,float的测试不对,(VS2010下)
周五被同事问到这个问题,不知原因,求解释!
...全文
239 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ken_scott 2013-05-02
  • 打赏
  • 举报
回复
引用 9 楼 libralibra 的回复:
刚在code::blocks12.11上试了下,没报警,晕
用的什么编译器?我也是12.11,gcc4.7.2默认参数编译.[/quote] 没注意看,家里的机器,也是默认的编译器, 难道是我的编译配置弄出问题了? 我有改过配置,但应该是往严格的方向改的。。。 谢谢了,我自己回去再看看好了
libralibra 2013-05-01
  • 打赏
  • 举报
回复
引用 7 楼 ken_scott 的回复:
[quote=引用 1 楼 libralibra 的回复:] 建议用gcc编译一下看看,原因是:通过‘...’传递时‘float’被提升为‘double’.
刚在code::blocks12.11上试了下,没报警,晕[/quote] 用的什么编译器?我也是12.11,gcc4.7.2默认参数编译.
ken_scott 2013-05-01
  • 打赏
  • 举报
回复
结贴!再次感谢
ken_scott 2013-05-01
  • 打赏
  • 举报
回复
引用 1 楼 libralibra 的回复:
建议用gcc编译一下看看,原因是:通过‘...’传递时‘float’被提升为‘double’.
刚在code::blocks12.11上试了下,没报警,晕
ken_scott 2013-05-01
  • 打赏
  • 举报
回复
ok, thank you!
qq120848369 2013-05-01
  • 打赏
  • 举报
回复
楼上正解。。
AnYidan 2013-04-30
  • 打赏
  • 举报
回复
va_arg 宏的第二个参数不能是 char, short, 它们会被提升为 int, flaot 被提升为double. 又是隐式转换惹的祸
图灵狗 2013-04-30
  • 打赏
  • 举报
回复
这个问题问的很经典,非常有代表性,印象中《C陷阱与缺陷》里面有涉及到。 简单的说,用va_arg(ap,type)取出一个参数的时候, type绝对不能为以下类型: char、signed char、unsigned char short、unsigned short signed short、short int、signed short int、unsigned short int float 原因是会对每个参数执行“默认实际参数提升(default argument promotions)”机制, char、short和相应的signed、unsigned类型的实际参数提升到int 如果int不能存储原值,则提升到unsigned int float类型的实际参数将提升到double
Athenacle_ 2013-04-30
  • 打赏
  • 举报
回复
变参函数调用时,float会提升至double。 所以不要在va_arg中使用float类型
libralibra 2013-04-30
  • 打赏
  • 举报
回复
建议用gcc编译一下看看,原因是:通过‘...’传递时‘float’被提升为‘double’.



69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧