va_end
- マクロをリセットするarg_ptr
。正確にva_endとは何ですか?それはいつもそれを呼び出す必要がありますか?
可変引数リストにアクセスした後、arg_ptr
ポインタは通常va_end()
でリセットされます。リストを再作成する必要がある場合は必須ですが、行っていない場合は本当に必要ですか? 「には常にdefault:
が含まれています」というルールのような良い習慣ですか?
va_end
- マクロをリセットするarg_ptr
。正確にva_endとは何ですか?それはいつもそれを呼び出す必要がありますか?
可変引数リストにアクセスした後、arg_ptr
ポインタは通常va_end()
でリセットされます。リストを再作成する必要がある場合は必須ですが、行っていない場合は本当に必要ですか? 「には常にdefault:
が含まれています」というルールのような良い習慣ですか?
va_end
を使用してクリーンアップします。あなたはスタックを粉砕したくないのですか? man va_start
から
:
はva_end()
のva_startの各呼び出しは()と同じ関数ではva_endの対応する呼び出し()にマッチしなければなりません。 va_end(ap)の呼び出しの後、変数apは未定義です。 va_start()とva_end()で囲まれたリストの複数のトラバーサルが可能です。 va_end()はマクロまたは関数である可能性があります。
注単語必見の存在。
va_start()
が実行していることがわからないので、スタックが破損する可能性があります。 va_*
マクロはブラックボックスとして扱われます。すべてのプラットフォーム上のすべてのコンパイラは、それが望むものを何でもできる。それは何もしないかもしれない、またはそれはたくさんするかもしれません。
一部のABIはレジスタの最初のいくつかの引数を渡し、残りの部分はスタックに渡します。 va_arg()
より複雑な場合があります。与えられた実装がどのようにvarargsを行うかを調べることができます。これは興味深いかもしれませんが、移植可能なコードを記述する際には、それらを不透明な操作として扱う必要があります。
一般的な "パラメータはスタックに渡されました"実装では、va_end()は通常は空/空ではないと考えられます。しかし、伝統的なスキームが少ないプラットフォームでは、それが必要になります。プラットフォームの中立性を維持するためにそれを含めることは「良い習慣」です。 Linuxの
すべてのvar_argsに対して繰り返し処理を行わなかった場合は、スタックをリセットすることができます。 – Spidey
は一つだけトラバーサルがva_list
変数の上に行うことができますx86-64で。より多くのトラバーサルを行うには、最初にva_copy
を使用してコピーする必要があります。 man va_copy
詳細を説明:
va_copyの()
明らかva_listの実装は、variadicな関数の スタックフレームへのポインタでなければなりません。こうした設定では(はるかに多い )があり、それ (長さ1の)ポインタの配列にするシステムもあり、そこに一つは
を必要とし、va_list aq = ap;
残念なことに割り当てに対して何も存在しないようです
va_list aq; *aq = *ap;
最後に、引数がレジスタに渡されるシステムでは、それは(そののva_argよう、またのva_start()、 を、メモリを割り当てるが、引数を格納する引数が次であるかの指示のために必要 であってもよいです)できます ステップリストを介して。今すぐva_end()は割り当てられたメモリ を解放することができます。このような状況に対応するために、C99)は、(はva_endの対応invoca- ンにマッチしなければならない)、上記割り当ては
va_list aq; va_copy(aq, ap); ... va_end(aq);
va_copyの各呼び出し(置き換えを行うことができるマクロva_copyの()、そう を追加します同じ機能で va_copy()を提供していないシステムでは、代わりに__va_copyが使用されています。これは、 ドラフト提案で使用されている名前であるためです。
これをcliarfyするには。 Linux x86-64では特別なことはありません。あなたが 'va_list'変数だけを利用可能にしているときにリストを2回反復したい場合、' va_copy'が必要です。 (例えば、引数として 'va_list'を取る関数の中で)。あなたはいつでも 'va_start'と' va_end'をいつでも呼び出すことができます。 –
@MattMcNabb on x86-64 'va_list'はトラバーサル状態を維持します。 x86ではそうではありません。 –
@downvoter何が間違っていますか? –
本当に良い質問です。私は誰かがva_endがノーオペレーションではないアーキテクチャを記述することでそれに答えることを望みます。 – erikkallen
FYI:MSVS2008 - #define _crt_va_end(ap =(va_list)0) – Yarik
@erikkallen: "va_endを定義する"ためのgoogle検索を実行すると、本質的に無意味な定義である場合とそうでない場合がある、 op。 – PlasmaHH