呼び出し規約について言及している回答がいくつかあります。それらはあなたの質問とは何の関係もありません。使用する呼び出し規約に関係なく、パラメーターを宣言する順序は重要ではありません。同じ数のパラメーターがレジスターによって渡され、同じ量のパラメーターがスタックによって渡される限り、どのパラメーターがレジスターによって渡され、どのパラメーターがスタックによって渡されるかは問題ではありません。ネイティブ アーキテクチャのサイズ (32 ビットの場合は 4 バイト、64 ビットの場合は 8 バイト) よりもサイズが大きいパラメーターは、アドレスで渡されるため、小さいサイズのデータと同じ速度で渡されることに注意してください。 .
例を見てみましょう:
6 つのパラメーターを持つ関数があります。そして、1 つのパラメーターをレジスターで渡し、残り (この場合は 5) をスタックで渡す呼び出し規約を CA と呼び、2 つ目の呼び出し規約を CB と呼び、4 つのパラメーターをレジスターで渡し、残りを CB と呼びます。 (この場合は 2) スタックごと。
もちろん、その CA は CB よりも高速ですが、パラメーターが宣言されている順序とは関係ありません。CA の場合、最初に (レジスターによって) 宣言するパラメーターと、2 番目、3 番目、..6 番目 (スタック) で宣言するパラメーターに関係なく高速になり、CB の場合、レジスターに対して宣言する 4 つの引数に関係なく高速になります。そして、最後の2つのパラメーターとして宣言します。
さて、あなたの質問に関して:
必須の唯一の規則は、オプションのパラメーターは最後に宣言する必要があるということです。オプションのパラメータの後に、オプションではないパラメータを続けることはできません。
それ以外は、好きな順序で使用できます。私から言える唯一の強力なアドバイスは、一貫性を保つことです。モデルを選択し、それに固執します。
考慮できるいくつかのガイドライン:
- 宛先はソースの前に来ます。これは に近いはず
destination = source
です。
- バッファのサイズはバッファの後に来ます:
f(char * s, unsigned size)
- 最初に入力パラメーター、最後に出力パラメーター (これは、最初に提供したものと競合します)
しかし、パラメーターの順序について「間違った」または「正しい」というものはなく、普遍的に受け入れられているガイドラインさえありません。何かを選択し、一貫性を保ちます。
編集
パラメータを順序付ける「間違った」方法を考えました:アルファベット順:)。
編集 2
たとえば、CA の場合、vector(100) と int を渡す場合、vector(100) が最初に来る方が良いでしょう。つまり、レジスタを使用してより大きなデータ型をロードします。右?
いいえ。前述のとおり、データ サイズは関係ありません。32 ビット アーキテクチャについて話しましょう (同じ議論が 16 ビット、64 ビットなどのどのアーキテクチャにも当てはまります)。アーキテクチャのネイティブ サイズに関連するパラメータのサイズに関して考えられる 3 つのケースを分析してみましょう。
- 同じサイズ: 4 バイトのパラメーター。ここで話すことは何もありません。
- より小さいサイズ: 4 バイトのレジスタが使用されるか、4 バイトがスタックに割り当てられます。したがって、ここでも興味深いことは何もありません。
- より大きなサイズ: (例: 多くのフィールドを持つ構造体、または静的配列)。この引数を渡すためにどの方法が選択されても、このデータはメモリに常駐し、渡されるのはそのデータへのポインタ (サイズ 4 バイト) です。ここでも、スタック上に 4 バイトのレジスタまたは 4 バイトがあります。
パラメータのサイズは関係ありません。
編集 3
@TonyDがどのように説明したか、すべてのパラメーターにアクセスしない場合、順序は重要です。彼の答えを見てください。