2012-04-15 18 views
4

関数の各呼び出しに次の引数を読み込ませることによって、可変引数リストを再帰的に解析する関数を作成したいとしますか? va_listを次の関数に渡した後、私は呼び出し関数でva_listを使い続けるつもりはありません。va_listのargsを再帰的に解析することはできますか?

void VarArgRecursive(va_list args) { 
    int nextArg = va_arg(args, int); 
    if(nextArg != -1) { 
     printf("Next arg %d\n", nextArg); 
     VarArgRecursive(args); 
    } 
} 

void VarArgFunc(int firstArg, ...) { 
    va_list args; 
    va_start(args, firstArg); 
    VarArgRecursive(args); 
    va_end(args); 
} 

int main (int argc, char * const argv[]) { 

    VarArgFunc(20, 12, 13, -1); 

    return 0; 
} 

コードは私のシステム上でコンパイルし、出力が期待されている通り:

Next arg 12 
Next arg 13 

ので、この練習OKがで次のコードokがありますか?私はリストを検索し、va_listを次の関数に渡した後、呼び出し関数内のva_listの内容は未定義であることがわかりました。それは私の使い方については重要ではありません.va_listを次の(うまく、実際は同じ)関数に引き渡した後でva_listを使い続けることはしません。

http://c-faq.com/varargs/handoff.html

...次の関数にva_listの受け渡しの私の方法がOKであることを示しています。また、私はこのページをチェックしています。それは、1つの引数を読み込んだあとにもう1つの関数にva_listを渡して、呼び出した関数が次の引数を読み込むことを期待しているかどうかです。この質問に対するC++固有の回答がある場合、それはC++プログラムで使用されるため、これもOKです。

+0

C++について質問している場合は、C++にタグを付けます。 –

+0

'varargs'の使用は避けてください。 (IIRC)4.5以来のG ++で利用可能なバリデーションテンプレートを使用します.G ++のみを使用するので、他のコンパイラについてはわかりませんが、MSVCを除くすべてのメインストリームコンパイラはすでにサポートしています。しかし、私の主なポイント: 'varargs'は悪です。それは本当に長い間失望していましたが、それは 'printf()'ファミリーだけです。 – Griwes

+0

@Matthew Flaschen:va_listマクロとva_argマクロはC++ではなく、C++であると考えていたので、私はそれをC++にタグ付けしませんでした。私は私のポストでこれを説明することを考えていました。私はC++を学んでいるcプログラマーです。だから私はcのやり方をする傾向があります。私はC++でそれを行う別の方法があったのか分からなかった。 – Balthazar

答えて

1

あなたは好きなだけ何回も渡すことができますが、va_listを複数回「使用」することはできません。消費されると、va_listが変更され、C++仕様ごとに未定義の動作が再度使用される可能性があります。

複数回使用する場合は、va_copyを呼び出して消費する前にva_listをクローンし、コピーを渡します。

しかし、あなたの場合、あなたがしていることは容認できます。 va_list を最初からの別の関数に渡そうとすると、問題が発生します。

+0

よろしくお願いいたします。私はそれが何か異議があるかどうかを見るためにそれを待ったが、私は誰も見ない、それが受け入れられたとしてマークしている... :) – Balthazar

関連する問題