2

したがって、次のコードを記述した場合:

MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);

プログラムは、終了時にアクセス違反でクラッシュします。次のようなコードを書くと:

int a;
a = MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);

クラッシュしません。引数の不一致に関して、私が尋ねた別の質問のおかげで、クラッシュしたときにクラッシュする理由がわかりましたが、クラッシュする理由はわかりません。

では、なぜこれが APPCRASH を引き起こすのでしょうか? 私は常に、戻り値の型を持つ関数を実際に渡さずに呼び出すことは安全であるという印象を受けていました。例:

int SomeFunction (void) {
   std::cout << "Hello ya'll!\n";
   return 42;
}

int main (void) {
   int a;

   // "Correct" ?
   a = SomeFunction();
   a = MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);

   // "Incorrect" ?
   SomeFunction();
   MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);

}

この種のテストを「クリーン」(新しいファイルで)実行すると、エラーは発生しません。私のプログラムで実行すると、 MessageBox/MessageBoxA でエラーが発生するようです。プロジェクトコードが大きすぎて投稿できないため、考えられる原因を知ることはエラーを特定するのに役立ちます (とにかく友人のコードを投稿するには友人の許可が必要です)。

追加情報:
コンパイラ = GCC
プラットフォーム = Windows

編集:

更新
これまでにフィードバックをお寄せいただきありがとうございます。だから私はデバッガーを介してそれを実行することにしました...今Code::Blocksは、プロジェクトファイル(* .cbp)からロードされない限り、プロジェクトをデバッグしません-AFAIK。そこで、実際のプロジェクトを作成し、プロジェクトのメイン ファイルをコピーしてプロジェクトに貼り付けました。その後、デバッグモードで実行しましたが、警告はあまり表示されませんでした。その後、ビルドモードでコンパイルしたところ、問題なく動作しました。
次に、Dev-C++ で新しいファイルを開き、デバッグとその後の最終ビルド プロセスを実行することにしましたが、ビルドでもデバッグでもエラーは発生しませんでした。私たちのメイン ファイル (Code::Blocks でエラーを引き起こすファイルのように) でも、Dev-C++ でこのエラーを再現できません。

まとめ
間違いは Code::Blocks にあるに違いありません。私の知る限り、どちらもGCCを使用しているため、かなり混乱しています。私が考えることができる唯一のことは、バージョンの違いか、おそらくコンパイラの設定か、それと同じくらいわかりにくいものです。オプティマイザの設定やその他のコンパイラの設定で、この種のエラーが発生する可能性はありますか?

4

1 に答える 1

3

戻り値のあるバージョンは、スタックに int がもう 1 つあるため、クラッシュしません。誤ったコードがスタックの境界を超えて読み取り、アクセス違反が発生します。しかし、スタックにそれ以上ある場合、ガード ページにはヒットしません。エラーのあるコードが読み取れるだけであれば、問題はありませんが、まだ壊れています。

次のような WTF を誘発するコードが 1 つありました。

char dummy[52];
some_function();

ありがたいことに、ダミーを削除するとsome_functionクラッシュすることを説明する長いコメントがありました。それは非常に古いアプリケーションにあったため、誰もあえて触れようとせず、some_functionまったく別のモジュールであり、私たちが制御することはできませんでした。そうそう、そのアプリケーションは、製油所や原子力発電所などの産業施設で 20 年以上現場でスムーズに動作していました... ^_^

于 2013-04-02T14:01:07.237 に答える