設定
Cで関数を呼び出すときのデフォルトの引数の昇格についていくつか質問があります.C99標準(pdf)のセクション6.5.2.2「関数呼び出し」段落6、7、および8です(強調を追加し、簡単にするためにリストに分割します読む):
パラグラフ 6
- 呼び出された関数を示す式がプロトタイプを含まない型を持つ場合、各引数に対して整数昇格が実行され、型を持つ引数
float
は に昇格されdouble
ます。これらはデフォルト引数のプロモーションと呼ばれます。- 引数の数がパラメーターの数と等しくない場合、動作は未定義です。
- 関数がプロトタイプを含む型で定義されていて、プロトタイプが省略記号 (
, ...
) で終わっているか、昇格後の引数の型がパラメーターの型と互換性がない場合、動作は未定義です。- 関数がプロトタイプを含まない型で定義されており、昇格後の引数の型が昇格後のパラメーターの型と互換性がない場合、次の場合を除き、動作は未定義です。
- 一方の昇格型は符号付き整数型で、もう一方の昇格型は対応する符号なし整数型であり、値は両方の型で表現可能です。
- 両方の型は、文字型またはの修飾または非修飾バージョンへのポインター
void
です。
パラグラフ 7
- 呼び出された関数を示す式が、プロトタイプを含む型を持っている場合、引数は、割り当てによるかのように、対応するパラメーターの型に暗黙的に変換され、各パラメーターの型が宣言された型の非修飾バージョンになります。タイプ。
- 関数プロトタイプ宣言子の省略記号表記により、最後に宣言されたパラメーターの後で引数の型変換が停止します。デフォルトの引数昇格は、末尾の引数に対して実行されます。
パラグラフ 8
- その他の変換は暗黙的に実行されません。特に、引数の数と型は、関数プロトタイプ宣言子を含まない関数定義のパラメーターの数と型と比較されません。
私が知っていること
- デフォルトの引数の昇格は
char
andshort
toint
/unsigned int
andfloat
toですdouble
- 可変引数関数 ( など
printf
) のオプションの引数は、デフォルトの引数昇格の対象です。
記録として、関数プロトタイプに関する私の理解は次のとおりです。
void func(int a, char b, float c); // Function prototype
void func(int a, char b, float c) { /* ... */ } // Function definition
質問
私はこれらすべてを理解するのに本当に苦労しています。ここに私が持っているいくつかの質問があります:
- プロトタイプ化された関数とプロトタイプ化されていない関数の動作は、デフォルトの昇格や暗黙の変換などに関して、実際にそれほど異なるのでしょうか?
- デフォルト引数の昇格はいつ行われますか? いつもですか?それとも、特別な場合 (可変個引数関数の場合など) だけですか? 関数がプロトタイプ化されているかどうかに依存しますか?