主に、特定の目的を達成するために必要なためです。たとえば、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に組み込まれているかどうかはまだわかりませんが、組み込まれた場合、古いモデルのコードと新しいモデルのコードの間にかなりの「亀裂」が生じるのではないかと思います.