2017-02-01 5 views
0

C可変長引数は呼び出し先の側で完全に処理されているというのが私の理解されているが、あなたはCでは、発信者はvariadicsを特別扱いしていますか?

f(1, 2, 3.0) 

と機能fを呼び出した場合、コンパイラはあなたが宣言していたかどうか、通話のための同じコードを生成すること、すなわち、 f

void f(int, int, double); 

又は

void f(int, int, ...); 

このquestiのコンテキストとしてonはthis issueで、バリストFFI定義を持つRustの真に可変なC関数を呼び出します。もしバリデリックスが呼び出し側の観点から重要でないならば(もちろん型チェックから)、Rustは関数がバリデーションとして宣言された呼び出しのために異なるコードを生成することは私にとっては奇妙に思えます。

実際にはC仕様ではなく、ABI依存である場合は、System V ABIの回答に最も興味がありますが、これは読んだところから特別な処理呼び出し元側のバリデーションの

+1

私は信じています。 –

+0

@EugeneSh。その場合、私はSystem V ABIに最も関心があることを反映するために私の質問を更新しました – Textfield

+1

これは[この問題の重複しているようです](http://stackoverflow.com/questions/40216160/variadic-arguements -and-x64)もSystem V ABIに関係しています。何か違いはありますか? –

答えて

2

これは非ABI固有の回答です。

はい、正式には、発信者は可変引数を持つ関数を特別な方法で扱うことができます(一般的にはそうなります)。これは実際に標準化された時代からC言語ではすべての可変関数がプロトタイプで呼び出される前にと宣言されている必要があった理由です。 C89/90で宣言されていない関数を安全に呼び出すことは可能でしたが、そうする権限は可変関数にまで及んでいないことに注意してください。これらは常に事前に宣言しなければなりません。それ以外の場合、動作は未定義です。

若干異なる形式では、ルールは現代Cにまだあります。C99以降では宣言されていない関数を呼び出すことはできませんが、それでもプロトタイプの宣言は必要ありません。しかし、バリデーショナル関数は、呼び出される前にプロトタイプで宣言されたでなければなりません。その根拠は同じです:呼び出し側は、それが可変関数を呼び出していることを知っていなければならず、多分、呼び出しを別の方法で処理しなければなりません。

歴史的に、variadic関数を呼び出すときには完全に異なる呼び出し規約を使用する実装がありました。

+0

また、可変引数は、可変でないプロトタイプの存在下で実行されるのとは必ずしも同じではない型昇格の対象であることにも注意してください。 –

+0

@ジョン・ボリンジャー:おそらく宣言を必要とする実際の理由ですが、潜在的に異なるABIはありません。たとえば、AAPCSは、固定パラメータリスト関数と同じ規則を使用します。 – Olaf

+0

@Olaf:しかし、これらのプロモーションは、*プロトタイプ宣言*または(C89/90の場合)宣言のない関数を呼び出すというコンテキストで実行されるプロモーションと全く同じです。これはすぐにいいえ、これはプロトタイプ*を必要とする実際の理由ではないことを意味します。 – AnT

関連する問題