变量函数(va_arg)不适用于float,而printf有效吗?有什么区别?

Kus*_*vil 2 c c++ floating-point variadic-functions

我碰巧在两年的这个问题中遇到了类似的情况:

变量函数(va_arg)不适用于float?

有人说,当我们称之为的时候,问题是促使浮动加倍

    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给我们这样一个鼻子恶魔呢?

das*_*ght 5

这不是printf促进浮动参数double,它是编译器.换句话说,当您va_argprintf任何其他具有可变参数数量的函数获得控件时,所有floats都已被提升为doubles; 原始floats不可用于检索.

之间的差printfva_argprintf遵循由标准设立的规则,并请求一个提升的类型(即,参数double)时,看到在格式字符串对应的格式说明.因此,它成功地获得了double其中的提升值float,并产生所需的输出.

另一方面,当va_arg调用时val = va_arg(vl, float)它忽略了促销规则,并获得无效的表示.