0

重複の可能性:
未定義、未指定、および実装定義の動作

C++ の未定義の動作について理解を深めようとしています。C++ コンパイラが未定義の動作のいくつかのケースを意図的に検出するとします。たとえば、2 つのシーケンス ポイント間で変数を 2 回変更する場合です

x++ = 2;

その架空のコンパイラがそのような状況を確実に検出すると、生成されたマシン コードに 10 個の完全にランダムなマシン命令を発行すると言います。

C++ 標準によると、何かが UB として分類される場合、何が起こるかについての要件はありません。記述されている架空のコンパイラは C++ 標準に準拠していますか?

4

4 に答える 4

9

はい。標準は要件を課していないため、必要なことは何でもできます。

未定義の動作

誤ったプログラム構成または誤ったデータを使用したときに発生する可能性があるような、この国際規格が要件を課していない動作。

これは未定義の動作ですが、必ずしも良い例ではありません。g++ 4.4.1 では、以下でのコンパイルを拒否します:

エラー: 代入の左オペランドとして左辺値が必要です

後置インクリメントの結果は左辺値ではないためです。

于 2010-11-24T09:26:07.043 に答える
3

基本的に、そうです、それらの10の命令が等しく到達可能である場合に限ります。次のコードを検討してください。

int main () {
  if (false) {
    int x = 0; x++ = 2;
  }
  std::cout << "Hello, world" << std::endl;
}

UBはコンパイル時に検出される可能性があり、その特定のブランチのコード生成により、意味のないコードが生成される可能性があります。ただし、それほど条件のないジャンプは、これをすべてスキップして、クロージングをまっすぐ通過する必要があります}

(ランタイムUBのコンパイル時の検出は以前にカバーされていなかったため、この質問は重複していません)

于 2010-11-24T09:46:02.653 に答える
2

特定のコンパイラ (バグがない限り) は、(コードのコンテキストが異なる場合を除いて) そのような構造に遭遇すると、常に同じ動作をします (間違いなくランダム コードはありません)。

実際には、「未定義の動作」とは、「コンパイラが異なれば処理が異なる」ことを意味します。

「架空のコンパイラは引き続き C++ 標準に準拠しますか?」- 私が思う答えはイエスです。

于 2010-11-24T09:30:25.433 に答える
0

ドラフト標準から / http://www.kuzbass.ru:8086/docs/isocpp/intro.html / [1.3.12]

[注: 許容される未定義の動作は、状況を完全に無視して予測不可能な結果を​​もたらすことから、翻訳中またはプログラム実行中に環境に特有の文書化された方法で動作すること (診断メッセージの発行の有無にかかわらず)、翻訳または実行の終了 (診断メッセージが発行されます)。多くの誤ったプログラム構造は、未定義の動作を引き起こしません。それらは診断される必要があります。]

間違いなく、ランダムな命令の挿入をリストしていません。また、リストされた動作の間の連続体のどこかにランダムな命令を挿入するという決定が「範囲」の側面に含まれると主張するのは困難です。;-)

于 2010-11-24T23:27:41.867 に答える