21

float パラメーターを取る可変個引数関数があります。うまくいかないのはなぜですか?

va_arg(arg, float)
4

2 に答える 2

49

対応する関数のパラメーターは、可変個引数関数に渡される前に...プロモートされます。charshort昇格intfloatに昇格doubleなど。

6.5.2.2.7関数プロトタイプ宣言子の省略記号により、最後に宣言されたパラメーターの後で引数型の変換が停止します。デフォルトの引数の昇格は、末尾の引数に対して実行されます。

この理由は、Cの初期バージョンには関数プロトタイプがなかったためです。パラメータタイプは関数サイトで宣言されましたが、呼び出しサイトでは認識されませんでした。ただし、型が異なれば表現も異なり、渡された引数の表現は、呼び出された関数の期待値と一致する必要があります。char値とshort値をintパラメーターを持つ関数に渡すことができるように、またはfloat値をdoubleパラメーターを持つ関数に渡すことができるように、コンパイラーは小さいタイプを大きいタイプに「プロモート」しました。この動作は、パラメータのタイプが呼び出しサイトで不明な場合、つまり、可変個引数関数またはプロトタイプなしで宣言された関数(たとえばint foo();)で引き続き見られます。

于 2012-06-30T00:49:50.690 に答える
10

@dasblinkenlightが述べたように、floatはdoubleにプロモートされます。それは私にとってはうまくいきます:

#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;
}

出力:

3.300000
4.400000
于 2012-06-30T00:54:29.040 に答える