float パラメーターを取る可変個引数関数があります。うまくいかないのはなぜですか?
va_arg(arg, float)
float パラメーターを取る可変個引数関数があります。うまくいかないのはなぜですか?
va_arg(arg, float)
対応する関数のパラメーターは、可変個引数関数に渡される前に...
プロモートされます。char
にshort
昇格int
、float
に昇格double
など。
6.5.2.2.7関数プロトタイプ宣言子の省略記号により、最後に宣言されたパラメーターの後で引数型の変換が停止します。デフォルトの引数の昇格は、末尾の引数に対して実行されます。
この理由は、Cの初期バージョンには関数プロトタイプがなかったためです。パラメータタイプは関数サイトで宣言されましたが、呼び出しサイトでは認識されませんでした。ただし、型が異なれば表現も異なり、渡された引数の表現は、呼び出された関数の期待値と一致する必要があります。char値とshort値をintパラメーターを持つ関数に渡すことができるように、またはfloat値をdoubleパラメーターを持つ関数に渡すことができるように、コンパイラーは小さいタイプを大きいタイプに「プロモート」しました。この動作は、パラメータのタイプが呼び出しサイトで不明な場合、つまり、可変個引数関数またはプロトタイプなしで宣言された関数(たとえばint foo();
)で引き続き見られます。
@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