2

コンパイラー/インタープリター言語拡張の理由は理解していますが、有効な定義を持たない動作がコンパイラーエラーをスローするのではなく、サイレントに失敗したり奇妙なことをしたりすることが許可されているのはなぜですか? コンパイラがそれらをキャッチするのが非常に難しい(不可能または単に時間がかかる)ためですか?

PS どの言語に未定義の動作があり、どの言語がないのですか?

PPS 不可能ではない/コンパイルでキャッチするのに時間がかかりすぎる未定義の動作のインスタンスはありますか?もしそうなら、それらの正当な理由/言い訳はありますか?

4

3 に答える 3

4

C や C++ などの言語では、未定義の動作の概念が必要です。これは、未定義の動作を引き起こす条件を検出することが不可能であるか、法外にコストがかかるためです。たとえば、次のコードを見てください。

int * p = new int(0);
// lots of conditional code, somewhere in which we do
int * q = p;
// lots more conditional code, somewhere in which we do
delete p;
// even more conditional code, somewhere in which we do
delete q;

ここでは、ポインターが 2 回削除されているため、未定義の動作が発生します。C や C++ などの言語では、エラーを検出するのは非常に困難です。

于 2010-05-10T11:41:58.820 に答える
3

主に、特定の目的を達成するために必要なためです。たとえば、C と C++ はもともと、デバイス ドライバーなどのオペレーティング システムを作成するために使用されていました。そのために、彼らは (とりわけ) I/O デバイスを表す特定のハードウェアの場所への直接アクセスを使用しました。これらの場所へのアクセスを禁止すると、C が本来の目的で使用されなくなります (C++ は、C と同じ機能をすべて許可することを明確にターゲットにしていました)。

もう 1 つの要因は、言語の指定とプラットフォームの指定の間の非常に基本的な決定です。同じ例を使用すると、C と C++ はどちらも、定義を言語に制限し、その言語を取り巻くプラットフォームを分離するという意識的な決定に基づいています。Java と .NET を最も明白な例として挙げたかなりの数の代替案では、代わりにプラットフォーム全体を指定しています。

これらはどちらも、デザインに対する考え方の基本的な違いを反映しています。C の設計 (大部分は C++ に保持されている) の基本的な教訓の 1 つは、「プログラマーを信頼する」ことでした。それほど直接的に述べられたことはありませんが、Java の基本的な「サンドボックス」の概念は、プログラマーを信頼してはならないという考えに基づいています。

どの言語が未定義の動作をする/しないかに関する限り、それはちょっとした秘密です: すべての実用的な目的のために、それらはすべて未定義の動作をします。一部の言語 (ここでも C と C++ が代表的な例です) は、どの動作が定義されていないかを指摘するために多大な努力を払っていますが、他の多くの言語は、それが存在しないと主張しようとするか (Java など)、「ダークコーナー」の多くをほとんど無視しています。 " 発生する場所 (たとえば、Pascal、ほとんどの .NET)。

それが存在しないと主張するものは、一般的に最大の問題を引き起こします. たとえば、Java には、一貫した浮動小数点の結果を保証しようとするかなりの数の規則が含まれています。その過程で、かなりの量のハードウェアで Java を効率的に実行することができなくなりますが、浮動小数点の結果の一貫性は依然として実際には保証されていません。さらに悪いことに、彼らが義務付けている浮動小数点モデルは完全ではないため、状況によっては、可能な限り最高の結果を得ることができなくなります (または、少なくとも、義務付けられていることを回避するために多くの余分な作業を行う必要があります)。

彼らの功績として、Sun/Oracle は (ようやく) この問題に気付き始めており、現在、改善すべきかなり異なる浮動小数点モデルに取り組んでいます。これがJavaに組み込まれているかどうかはまだわかりませんが、組み込まれた場合、古いモデルのコードと新しいモデルのコードの間にかなりの「亀裂」が生じるのではないかと思います.

于 2010-05-10T15:57:27.937 に答える
0

オペレーティング システムが異なれば動作も異なるため (...)、「この場合はクラッシュする」とだけ言うことはできません。オペレーティング システムの方がうまくいく可能性があるからです。

于 2010-05-10T11:45:52.223 に答える