2012-03-30 5 views
4

私はこのようにva_listの使用:va_listのとのva_arg

void foo(const char* firstArg, ...) { 
    va_list args; 
    va_start (args, firstArg); 
    for (const char* arg = firstArg; arg != NULL; arg = va_arg(arg, const char*)) { 
     // do something with arg 
    } 

    va_end(args); 
} 

のfoo( "123"、 "234"、 "345")

最初の3つの引数が正しくfooへの渡されましたが、ここで " 345" は

arg = va_arg(arg, const char*) 

が引数にいくつかの他のフリーク値を設定し、実行されます。

だから何が問題なのですか?私はコンパイラとしてllvm3.0を使用しています。

+0

OK、私はこの 'foo(" 123 "、" 234 "、" 345 "、NULL)'のようにします。私はそれが動作するかどうかをテストします。 – holsety

+1

'(char *)NULL'は実際に渡すべきです。' NULL'はプレーンな0として定義され、コンパイラはキャストのないポインタ値を暗黙的に知る方法がありません。これは、sizeof(int)!= sizeof(char *) 'が64ビット実装で珍しくない場合に特に重要です。 – FatalError

+2

実際はそうではありません。 C11では、§7.19の ''は、マクロが NULLであることを示しています。実装定義のNULLポインタ定数に展開される _壊れた実装だけが、NULLポインタと等価でない方法でNULLを定義できる。セクション§7.17の「」のC99の文言は同じで、C89も本質的に同じだと私は信じています。 –

答えて

4

私は次のようにループがあるべきだと思う:

for (const char* arg = firstArg; arg != NULL; arg = va_arg(args, const char*)) 

変更はva_arg(args, const char*)代わりのva_arg(arg/*<<==*/, const char*)です。

10

Cは、...引数リストの最後にNULLを自動的に挿入しません。引数の最後を検出するのにNULLを使用する場合は、明示的に渡す必要があります。一部の関数(printfなど)では、以前のパラメータを使用して引数の終わりに達した時点を判断します。

編集:そして実際にあなたが最後にNULLを置きたい場合、あなたはそれがNULLポインタの正しいタイプとして渡されるように、適切な型にキャストする必要があります。)

+0

も参照してください。 'printf()'が ''引数の終わり 'に達したときに、どのようになるかを示す情報やリンクを教えてください。 printf()の働きは、他の '可変数の引数を持つ関数'の働きとまったく同じですか? – barnes

+1

パーセント記号の数を数えます。 –

+0

私は 'printf()'が 'va_list()'型の2つのポインタを使用していると仮定しています。 1つは '%'の引数とその他にトラックを保持するものです。そうですか? – barnes

関連する問題