5

関数の呼び出しごとに次の引数を読み取らせて、可変引数リストを再帰的に解析する関数を作成したいとします。va_list を次の関数に渡した後、呼び出し元の関数で va_list を使用し続けるつもりはありません。次のコードは大丈夫ですか:

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

では、この練習は大丈夫ですか?リストを検索したところ、va_list を次の関数に渡した後、呼び出し元の関数の va_list の内容が未定義であることがわかりました。次の(実際には同じ)関数に渡した後、va_list を使用し続けることはないため、これは私の使用法には関係ありません。このページもチェックしました:

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

...これは、va_list を次の関数に渡す方法が正しいことを示しています。それが言っていないのは、1 つの引数を読み取った後に va_list をさらに別の関数に渡し、呼び出された関数が次の引数を読み取ることを期待してもよいかどうかです。この質問に対する c++ 固有の回答がある場合、それは c++ プログラムで使用されるため、それも問題ありません。

4

1 に答える 1

1

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

複数回使用する場合は、va_copyを呼び出してva_listのクローンを作成してから使用し、コピーを渡します。

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

于 2012-04-15T18:05:23.617 に答える