1. ホーム
  2. c++

[解決済み] 未定義の動作」は本当に何でもありなのか?重複

2023-01-16 15:46:24

質問

未定義の動作の古典的な例として、もちろん、C や C++の標準が何を許可しているかにかかわらず、物理的に不可能な鼻の悪魔があります。

C や C++のコミュニティでは、未定義の動作の予測不可能性や、コンパイラーがプログラムに文字通り「未定義の動作」をさせることが許されるという考え方に重点を置く傾向があるため、「未定義の動作」は「未定義の動作」ではなく「未定義の動作」なのです。 何でも という考えを強調する傾向があるため、私は、標準では未定義の動作に何の制限もないと思っていました。

しかし は、C++ 標準の関連する引用文のようです。 :

[C++14: defns.undefined]: [..] 許容される未定義の動作は、予測できない結果をもたらす状況の完全無視から、翻訳中またはプログラム実行中に環境に特有の文書化された方法で動作すること (診断メッセージの発行の有無を問わず)、翻訳または実行を終了すること (診断メッセージの発行あり) まで、多岐にわたります。 [..]

これは実際に可能なオプションの小さなセットを指定します。

  • 状況を無視する -- 確かに、この規格はこれが "予測不可能な結果をもたらすと言い続けていますが、それはコンパイラが を挿入することとは異なります。 コードを挿入することとは異なります (これは、ほら、鼻くそ悪魔の前提条件だろうと推測します)。
  • 環境に特徴的な文書化された方法で動作する -- これは実際には比較的穏やかな響きです。(確かに、鼻の悪魔のような文書化されたケースは聞いたことがありません)。
  • 翻訳または実行の終了 -- 診断付きで、いや、それ以下でもない。すべての UB がそのようにうまく動作してくれればよいのですが。

たとえば、初期化されていないメモリを読み込む場合、一貫した動作を保証するために何らかのコードを挿入することは、おそらく最適化の妨げになるでしょう。未定義の動作のうち、奇妙なもの(例えば、" タイム トラベル しかし、これは、そのような動作が文書化され、環境の特徴であることを必要とします (つまり、鼻の悪魔は地獄のコンピューターによってのみ生成されるのでしょうか?)。

私はこの定義を誤解しているのでしょうか?これらは単なる として意図されているのでしょうか? 何でも起こりうるという主張は、単に状況を無視することによる予期せぬ副作用として意図されているのでしょうか?

明確化のための 2 つのマイナーなポイント。

  • 元の質問から明らかだと思いましたし、ほとんどの人にとってはそうだと思いますが、とにかく綴っておきます。私は、quot;nasal demons" が皮肉であることを理解しています。
  • UB がプラットフォーム固有のコンパイラー最適化を可能にすることを説明する (他の) 答えを書かないようにしてください。 また がどのように最適化されるのかを説明してください。 実装で定義された 動作 ではありません。 を許可します。

この質問は、未定義の動作の (誤った) メリットについての議論の場として意図されたものではありませんでしたが、そのようなものになってしまいました。いずれにせよ 未定義の動作がない仮想的な C コンパイラーに関するこのスレッド は、これが重要なトピックであると考える人々にとって、さらなる関心事であるかもしれません。

どのように解決するのですか?

そうです、それはどんなことでも許可します。注釈は例を挙げているだけです。定義はとても明確です。

未定義の動作:この国際規格が要求事項を課していない動作。


よくある混乱ポイント。

要求がないことを理解する必要があります。 というのは、実装が ではない は、動作を未定義のままにしたり、奇妙なことや非決定的なことをする必要がないことを意味します!

実装は、C++標準によって、いくつかのまともな動作を文書化し、それに従って動作することが完全に許可されています。 1 ですから、もしあなたのコンパイラが符号付きオーバーフローで折り返すと主張するならば、論理(正気か? そのコンパイラーで . ただ、他のコンパイラーが同じように動作することを期待しないでください。

1 ヘックは、あることを文書化し、別のことをすることさえ許されています。それは愚かなことであり、おそらくゴミ箱に捨てることになるでしょう - ドキュメントが嘘をつくコンパイラーをなぜ信用できるのでしょうか?