純粋に興味のために、私はCを再学習しています...私は知りません...15-20年。
可変引数が単純なマクロとして実装されたことを思い出しているようです。
- 誰かが彼らが何であったか覚えていますか?
編集:私の質問を明確にするために、それらがva_listなどと同じ名前を持っていることを知っていますが、実際のマクロ定義を覚えていますか?
- 彼らは今日でも機能しますか?
純粋に興味のために、私はCを再学習しています...私は知りません...15-20年。
可変引数が単純なマクロとして実装されたことを思い出しているようです。
編集:私の質問を明確にするために、それらがva_listなどと同じ名前を持っていることを知っていますが、実際のマクロ定義を覚えていますか?
あなたは、、、、およびstdarg.h(WPの記事へのリンクva_list
)から考えています。彼らはまだうまく動作します。:-)va_arg
va_start
va_end
可変個引数関数は、実際、マクロを使用して実際に一般的に実装されます。これらは標準化されています-このテーマに関するこのウィキペディアの記事を参照してください。実際のマクロ定義は、コールスタックを使用して移植性のないゲームをプレイする必要があるため、プロセッサアーキテクチャに依存します。
標準化の前でさえ、可変引数を実行する方法は一般的でした。C89標準は、既存の慣行に基づいて...標準化されたインターフェイスを提供しました。これらのプラクティスの残りはまだ存在しています。たとえば<varargs.h>
、Unix98にはまだ存在していました:http ://www.opengroup.org/onlinepubs/007908799/xsh/varargs.h.html (ただし、現在のバージョンには存在しません)
マクロの実装は常にシステムに大きく依存していました(スタックは両方向に成長し、スタックとしてリンクリストを使用するシステムもあります。スタックフレーム内のさまざまなものの位置はプロセッサに依存し、一部のプロセッサでは一般的な規則に依存します) --Sparcによると--最初にレジスタを保存する必要があります。アライメント要件により問題が発生する可能性があります...)
単純な実装がどのように見えるかを知りたい場合は、おそらく誤った仮定に応じて(正しく配置しようとはしません)、仮定が成り立つ場合でも確かにいくつかのコーナーケースに失敗します。
typedef void* va_list;
#define va_start(va, arg) va = (void*)((&arg)+1)
#define va_arg(va, type) (va = (void*)(((type*)va) + 1), *((type*)va -1)
#define va_end(va)
今日の可変引数は、で説明されているインターフェイスを介して行われます<stdarg.h>
-15年前にどのように行われたかについては、私は本当に言えません。
昔からの実装がまだ機能するかどうかはわかりませんが、他の人が指摘しているものとほとんど同じであり、標準のヘッダーに移動しただけです(標準は有効な単語です)。
コンパイラーが組み込みとして拡張するのは、コンパイラーと、それを呼び出すときにコンパイラーに渡すフラグです。
gccは唯一のCコンパイラではありませんが、(他のコンパイラと同様に)c89およびc99に準拠していることに注意してください。