0

GCCは通常、適切なヘッダーファイルがインクルードされていない場合にこの警告を生成します。このリンク-> www.network-theory.co.uk/docs/gccintro/gccintro_19.htmlは、関数宣言が(ヘッダーを介して明示的に宣言されるのではなく)暗黙的であるため、間違った引数タイプが実際に関数に渡される可能性があることを示しています、誤った結果が得られます。わかりません。これは、コンパイラが、マシンのワードサイズの何かを、呼び出し先が消費できるようにスタックにプッシュし、最高のものを期待するコードを生成することを意味しますか?

詳細は大歓迎です。

4

2 に答える 2

4

プロトタイプがない場合や、プロトタイプに省略記号 ('...') がある場合に渡される引数の場合など、引数を渡す方法に関する特定の情報がコンパイラにない場合、コンパイラは渡すための特定の規則に従います。引数。これらの規則は基本的に、プロトタイプが使用される前の標準化前 (または K&R) C で発生したものに従います。C99 6.5.2.2/6「関数呼び出し」からの言い換え:

* the integer promotions are applied
* if the argument has float type it's promoted to double

これらのデフォルトの引数プロモーションが適用された後、引数は、コンパイラが通常引数をコピーする場所 (通常はスタック) に単純にコピーされます。したがって、構造体の引数がスタックにコピーされます。

実際の関数の実装が、コンパイラがパラメーターを作成する方法と一致しない場合、未定義の動作が発生します (値を表すことができる場合、または char へのポインターと void へのポインターを混在/一致させることができる場合は、符号付き/符号なしの不一致は例外です)。

また、C90 では、関数が暗黙的に宣言されている場合 (C99 では許可されていませんが、プロトタイプなしの関数は許可されています)、戻り値はデフォルトで として設定されintます。繰り返しますが、実際の関数は別のものを返し、未定義の動作が発生します。

于 2011-06-27T04:37:49.150 に答える
3

従来のK&R Cでは、それがほとんど起こったことです。デフォルトの強制(たとえば、(int)昇格されたものよりも小さいもの(int))があり、下位互換性のために、プロトタイプのない関数は引き続きそのように呼び出されますが、概して、間違ったタイプを渡すことで得られた唯一の兆候は、奇妙な結果または多分コアダンプ。関数にプロトタイプがある場合、正確な(強制/プロモートされていない)値がプッシュされるため、ここで問題が発生します。したがって、を渡す(char)場合、スコープ内にプロトタイプがある場合は、呼び出し元によって1バイトがプッシュされます。それ以外の場合は、4バイトがプッシュされます(現在のほとんどのプラットフォーム)。発信者と着信者がこれについて同意しない場合、悪いことが起こります。

于 2011-06-27T03:56:22.223 に答える