• ベストアンサー

va_list型について

あるC言語のソースを見ていたら、va_list型の引數を持つ函數がありました。 そのソースは複雜なので、質問するために以下のソースを作りました。 (ですから、このプログラムはじつよう性もないし、無意味なこともしています。) #include <stdio.h> #include <stdarg.h> int sum_func1(int sw1, va_list ap1) { int sum1 = 0; va_start(ap1, sw1); sum1 += va_arg(ap1,int); sum1 += va_arg(ap1,int); va_end(ap1); return(sum1); } int sum_func0(int sw0, ...) { int sum0; va_list ap0; int a0, b0; va_start(ap0, sw0); a0=va_arg(ap0, int); b0=va_arg(ap0, int); printf("sum_func0です。これから%dと%dを足します。\n", a0, b0); sum0 = sum_func1(sw0, ap0); va_end(ap0); return(sum0); } int main(void) { printf("1 + 2 = %d\n", sum_func0(0,1,2)); return 0; } やっていることは、結局のところ、1と2を足してその結果を表示しているだけです。 このプログラムは動かすことはできますが、表示される足し算の結果がおかしいです。 sum_func0の中で 1(a0)と2(b0)は既にva_argを使って取得しています。 その後、sum_func1の中で、再び この1と2を取得しようとしているのですが、 このようなことは可能でしょうか。 可能ならば、どのように修整すればよいのでしょうか。 これが可能か否かが元のソースの讀み方に影響するのです。 最初に述べたように、va_list型の引數を持つ函數についての質問なので、 va_list型の引數を使わないような修整方法ですと、 期待するものではありません。

質問者が選んだベストアンサー

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

あと、sum_func1のなかの、va_start、va_endも不要ですね。

noname#2823
質問者

お礼

No2、No3 これはおもしろいですね。 もちろん、回答としては正解です。 これも單純化すると、次のような仕組みになっているんですね。 int sum_func0(int sw0, ...) { va_list ap0,ap1; va_start(ap0, sw0); ap1=ap0; va_arg(ap0, int); va_arg(ap0, int); va_arg(ap1, int); va_arg(ap1, int); va_end(ap0); ・ ・ } va_list型の變數が2つあるのがポイントですね。 これもap1から引數を取り出す部分を函數にすれば、質問に適しますね。

その他の回答 (2)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>va_start(ap0, sw0); >a0=va_arg(ap0, int); >b0=va_arg(ap0, int); va_argマクロは、ap0の内容を書き換えます。 そのため、sum_func1に正しい引数がわたっていません。 va_list ap0, ap1; va_start(ap0, sw0); ap1 = ap0; ・ ・ ・ sum0 = sum_func1(sw0, ap1); とすればsum_func1()で問題なく呼び元からの可変引数を利用できます。

  • e101tre
  • ベストアンサー率38% (7/18)
回答No.1

> sum_func0の中で 1(a0)と2(b0)は既にva_argを使って取得しています。 > その後、sum_func1の中で、再び この1と2を取得しようとしているのですが、 > このようなことは可能でしょうか。 va_start ~ va_end で囲めば、何回でも取得できるはずです。 以下に例を示します。 //int sum_func1(int sw1, va_list ap1) int sum_func1(va_list ap1) { int sum1 = 0; //va_start(ap1, sw1); sum1 += va_arg(ap1,int); sum1 += va_arg(ap1,int); //va_end(ap1); return(sum1); } int sum_func0(int sw0, ...) { int sum0; va_list ap0; int a0, b0; va_start(ap0, sw0); a0=va_arg(ap0, int); b0=va_arg(ap0, int); printf("sum_func0です。これから%dと%dを足します。\n", a0, b0); //sum0 = sum_func1(sw0, ap0); va_end(ap0); va_start(ap0, sw0); sum0 = sum_func1(ap0); va_end(ap0); return(sum0); }

noname#2823
質問者

お礼

なるほど~、と思いました。 ありがとうございました。 これは單純化して可變數個引數關係のみを拔き出して書くと、 次のように、va_start、va_endの組が、【入れ子にならずに】ならんでいますね。 int sum_func0(int sw0, ...) { va_list ap0; va_start(ap0, sw0); a0=va_arg(ap0, int); b0=va_arg(ap0, int); va_end(ap0); va_start(ap0, sw0); a0=va_arg(ap0, int); b0=va_arg(ap0, int); va_end(ap0); } あとは2番目の「va_start・va_endの組」の内側が、 va_list型ap0を引數とする函數になっているだけですね。 ご回答が私の質問に對して正解であるのは言うまでもないですが、 私の疑問は入れ子にすることはできないのだろうか、 ということでした。

関連するQ&A

専門家に質問してみよう