[解決済み] 未定義、未指定、および実装で定義された動作
質問
とは何ですか? 未定義の動作 (UB) in C and C++? についてはどうですか? 未定義の動作 と 実装定義 ビヘイビア? 両者の違いは何ですか?
どのように解決するのですか?
未定義の動作 は、他の言語から来たプログラマーが驚くようなC言語とC++言語の側面の1つです(他の言語はそれをうまく隠そうとしています)。基本的に、多くのC++コンパイラはプログラムのエラーを報告しないにもかかわらず、予測可能な方法で動作しないC++プログラムを書くことが可能なのです!
典型的な例を見てみましょう。
#include <iostream>
int main()
{
char* p = "hello!\n"; // yes I know, deprecated conversion
p[0] = 'y';
p[5] = 'w';
std::cout << p;
}
変数
p
は、文字列リテラル
"hello!\n"
そして、以下の2つの代入は、その文字列リテラルを変更しようとするものです。このプログラムはどうなっているのでしょうか?C++標準のセクション2.14.5パラグラフ11によれば、このプログラムは
未定義の動作
:
文字列リテラルを変更しようとした場合の効果は未定義です。
しかし、待ってください、私はこれを問題なくコンパイルして、出力を得ることができます。
yellow
文字列リテラルは読み取り専用メモリに保存されるため、最初の代入を試みるとコアダンプになります。これはまさに未定義の動作の問題です。基本的に、標準では未定義動作を呼び出したら何でもあり(鼻歌鬼でも)なのです。もし、あなたの言語のメンタルモデルに従った正しい動作があるとすれば、そのモデルは単に間違っているのであって、C++標準は唯一の投票権を持っています。
未定義の動作の他の例としては、境界を越えて配列にアクセスすることが挙げられます。
ヌルポインタの再参照
,
ライフタイム終了後のオブジェクトへのアクセス
または書き込み
巧妙と言われる表現
のように
i++ + ++i
.
C++標準の1.9項では、未定義動作の危険度の低い2つの兄弟についても言及しています。 無指定動作 と 実装で定義された動作 :
この国際規格の意味記述は,パラメタ化された非決定論的抽象機械を定義する。
抽象的な機械の特定の側面と操作は、この国際規格で次のように記述されています。 実装定義 (例)
sizeof(int)
). これらは抽象的な機械のパラメータを構成する。各実装には、これらの点に関する特性や動作を説明する文書を含める必要があります。抽象機械の他のある側面と操作は、この国際規格で次のように記述されています。 不特定多数 (例えば、関数への引数の評価順序など)。可能な場合、この国際規格は許容される動作のセットを定義する。これらは、抽象機械の非決定的な側面を定義する。
その他の特定の操作は、本国際規格で次のように記述されています。 未定義 (例えば、ヌルポインタをデリファレンスした場合の効果)。[ 備考 : この国際規格は、未定義の動作を含むプログラムの動作について、何らの要求も課さない。 - エンディングノート ]
具体的には、1.3.24項に記載されています。
許容される未定義の動作は、以下の通りです。 状況を完全に無視し、予測不可能な結果をもたらす 翻訳中やプログラム実行中に、環境に特徴的な文書化された方法で動作する(診断メッセージの発行の有無にかかわらず)、翻訳や実行を終了する(診断メッセージの発行あり)、などです。
未定義の動作に遭遇しないためには、どうしたらよいのでしょうか?基本的には C++の良書 自分の言っていることを理解している著者によるものです。インターネットのチュートリアルは避けましょう。ブルズチャイルドは避けてください。
関連
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み] 未定義の動作とシーケンスポイント
-
[解決済み] C言語とC++の両方で有効なコードを、それぞれの言語でコンパイルすると、異なる動作になることがありますか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】ストリクト・エイリアシング・ルールとは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】識別子 "string "は未定義?
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】変数やフィールドがvoid宣言されている