まず、C ++03標準からのいくつかの定義:
1.3.5実装定義の動作
実装に依存し、各実装が文書化する、整形式のプログラム構成と正しいデータの動作
1.3.12未定義動作
この国際規格が要件を課していない、誤ったプログラム構成または誤ったデータの使用時に発生する可能性があるような動作。この国際規格で明示的な定義または動作の説明が省略されている場合も、未定義の動作が予想される場合があります。
1.3.13不特定の動作
実装に依存する、整形式のプログラム構成と正しいデータの動作。どの動作が発生するかを文書化するために実装は必要ありません。
不特定の振る舞いはUBと呼ばれる可能性がありますが、私はそれを見たことがありません。UBは常に未定義の振る舞いを意味します。 標準全体を通して、「Xを実行することは未定義の動作です」と同様のステートメントがありますが、単にカバーされていないケースに遭遇することがあります。
別の言い方をすれば、どこかに未定義の動作がある場合、すべての賭けはオフになります。標準に関する限り、あなたのプログラムは、スーパーボウルの週末に義母を招待することから、nethackを実行することまで、何でもすることができます。UBの性質上、テストすることはできず、コンパイラーからの支援を期待することもできません。(いくつかの些細なことですが、一般的なエラーコンパイラは一般的に診断を生成します。)
通常、何かがUBとして定義されるのは、論理的に意味がないため(たとえば、範囲外の配列にアクセスする場合)ですが、多くの場合、実行時に実装で防止するために多くの作業を行う必要があるためです。C ++はCから派生していることを忘れないでください。高度に最適化されたプログラムを作成できることは、両方の言語の主要な目標です。この目的のために、言語はプログラマーに任せて、「使用しないものに対してお金を払わない」という原則に関連して、これらの状況でコードが正しいことを確認します。
つまり、最後に、UBは悪い、非常に悪いです。絶対に避けてください。ただし、UBの難しい部分は、それが何であるか、またはどのような状況で発生するかを認識していません。難しいのは、UBを呼び出すときに認識することです。例えば:
std::string s = "abc";
char& c = s[0];
cout.write(s.data(), s.length());
c = '-';
完全に合理的に見えますよね?いいえ、これはUBですが、一般的なすべての実装で期待どおりに機能します。