Kus*_*vil 2 c c++ floating-point variadic-functions
我碰巧在两年的这个问题中遇到了类似的情况:
有人说,当我们称之为的时候,问题是促使浮动加倍
va_arg(arg, float)
Run Code Online (Sandbox Code Playgroud)
我的问题是在这篇文章的最后,但首先让我们来看看@ Jack在上面链接的问题下面的答案:
#include <stdio.h>
#include <stdarg.h>
void foo(int n, ...)
{
va_list vl;
va_start(vl, n);
int c;
double val;
for(c = 0; c < n; c++) {
val = va_arg(vl, double);
printf("%f\n", val);
}
va_end(vl);
}
int main(void)
{
foo(2, 3.3f, 4.4f);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
3.300000
4.400000
Run Code Online (Sandbox Code Playgroud)
现在,如果我们改变val = va_arg(vl, double)成val = va_arg(vl, float),我们会得到(至少我得到了2012 MSVS):
36893488147419103000.000000
2.162500
Run Code Online (Sandbox Code Playgroud)
我们现在回答我的问题.
在这个主题:C/C++ va_list没有正确地返回参数
最多的投票答案,它的评论说,这printf也促进了 float 's to double.
但有什么区别?如果他们两个都float进入double,为什么要printf正确地写出值,同时va_arg给我们这样一个鼻子恶魔呢?
这不是printf促进浮动参数double,它是编译器.换句话说,当您va_arg或printf任何其他具有可变参数数量的函数获得控件时,所有floats都已被提升为doubles; 原始floats不可用于检索.
之间的差printf和va_arg是printf遵循由标准设立的规则,并请求一个提升的类型(即,参数double)时,看到在格式字符串对应的格式说明.因此,它成功地获得了double其中的提升值float,并产生所需的输出.
另一方面,当va_arg调用时val = va_arg(vl, float)它忽略了促销规则,并获得无效的表示.