2

このコードが準拠している理由がわかりません:

int array[100];
array[-50] = 100; // Crash!!

...コンパイラは、コンパイルエラーや警告なしに、引き続き正しくコンパイルされます。

では、なぜそれがコンパイルされるのでしょうか?

4

5 に答える 5

7
array[-50] = 100;

実際にはここを意味します:

*(array - 50) = 100;

このコードを考慮してください:

int array[100];
int *b = &(a[50]);
b[-20] = 5;

このコードは有効で、クラッシュしません。コンパイラーは、コードがクラッシュするかどうか、およびプログラマーが配列で何をしたかったかを知る方法がありません。だから文句は言わない。

最後に、コード内のバグを見つける際にコンパイラの警告に頼るべきではないことを考慮してください。コンパイラーほとんどのバグを見つけられず、バグ修正プロセスを容易にするためのヒントをほとんど作ろうとしません (時には、コンパイラーは間違っていて、有効なコードにバグがあると指摘することさえあります)。また、標準では実際にはコンパイラが警告を発することを要求していないため、これらはコンパイラの実装者の善意による行為にすぎません。

于 2013-02-12T13:13:32.593 に答える
6

array[-50]式が同等に変換されるため、コンパイルされます

*(&array[0] + (-50))

これは別の言い方をすれば、「メモリ アドレス&array[0]を取得してそれに -50 回加算しsizeof(array[0])、結果のメモリ アドレスの内容とそれに続く内容をint"として解釈します。通常のポインター算術規則に従って。これは完全に有効な式で-50あり、実際には任意の整数である可能性があります (もちろん、コンパイル時の定数である必要はありません)。

here-50 コンパイル時の定数であり、配列のマイナス 50 番目の要素へのアクセスはほとんどの場合エラーであるため、コンパイラはこれに対して警告を生成できます (おそらく生成する必要があります)。

ただし、この特定の状態の検出 (明らかに無効なインデックスを持つ配列への静的なインデックス付け) は、実際のコードでは見られないものであることも考慮する必要があります。したがって、コンパイラ チームのリソースは、おそらく他のことを行うために有効に活用されるでしょう。

これを、実際のコードで見られると予想される (タイプミスが非常に簡単であるという理由だけで)、デバッグが困難な (目には と簡単に読み取れるが、すぐに突き出てしまう)if (answer = 42)よう他の構成要素と比較してください。このような場合、コンパイラの警告ははるかに生産的です。===-50

于 2013-02-12T13:13:13.613 に答える
1

真のコンパイラはそうします(注: コンパイラを clang 3.2 に切り替える必要があります。gcc はユーザーフレンドリーではありません)。

Compilation finished with warnings:
source.cpp:3:4: warning: array index -50 is before the beginning of the array [-Warray-bounds]
array[-50] = 100;
^ ~~~
source.cpp:2:4: note: array 'array' declared here
int array[100];
^
1 warning generated.

劣った (*) コンパイラを使用している場合は、警告を手動で設定する必要がある場合があります。

(*) つまり、ユーザーフレンドリーではない

于 2013-02-12T13:13:06.243 に答える
1

コンパイラは、コンパイル時にすべての潜在的な問題をキャッチする必要はありません。C 標準では、実行時に未定義の動作が許可されます (これは、このプログラムの実行時に発生することです)。この種のバグを捕まえないための法的言い訳として扱うことができます。

ただし、このような些細なバグをキャッチできるコンパイラーと静的プログラム・アナライザーがあります。

于 2013-02-12T13:16:37.480 に答える
0

括弧内の数字は単なるインデックスです。要求している番号を見つけるために必要なメモリ内のステップ数を示します。 array[2]配列の先頭から開始し、前方に 2 回ジャンプすることを意味します。

50 回後方にジャンプするように指示しましたが、これは有効なステートメントです。しかし、これを行う正当な理由があるとは想像できません...

于 2013-02-12T13:15:21.207 に答える