「詳説cポインタ」を読んで未規定と未定義の違いがわからなくて、調べてみたのですがネットにも情報が少なく良くわかりません。
http://www.c-lang.org/detail/unspecified_behavior.html
http://www.c-lang.org/detail/undefined_behavior.html
わかりやすく教えていただけないでしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
質問文中で言及されているページに、既に厳密な説明がありますね。もう少しくだけた説明なら、下記ページ等が参考になるかと思います。
http://www.st.rim.or.jp/~phinloda/cqa/cqa7.htmlより引用:
Q 【未定義】
未定義とは何か。不定と何が違うのか。
A
未定義とは、その結果どうなるかが、言語仕様として決められていないことを意味します。そして、その結果がどうなっても、そのC言語の処理系はは規格に合致しているとみなされます。コンパイラは未定義のコードを処理する時に独自の解釈をしてもよいし、あるいは、不正なコードを生成して、実行した途端にシステムを停止させても構いません。コンパイル時にエラーにしても構いません。
.
インターネットのニュースグループ、comp.std.cやcomp.lang.cでは、未定義のコードを実行した結果「鼻から悪魔が飛び出しても仕様に反しない」というjokeが流行したことがありました。今でもたまにこのような表現を見ることがあります。
.
英語では、未定義のことをundefined、不定のことをunspecifiedと表現します。
.
不定と未定義の最も大きな違いは、不定のコードはプログラムとしては正しいが、未定義のコードは間違いであり、動作する保証すらないという所にあります。従って、未定義のコードは絶対に書くべきではありません。不定の場合は、結果がどのようになるかは処理系に依存しますが、プログラム自体は正しいとみなされることが保証されています。従って、 a = foo() + bar(); のようなコードは、どちらが先に呼ばれても構わない状況で用いる限り、安心して使うことができます。
.
JISでは未定義の動作について、次のように記述しています。「可搬性がない若しくは不正なプログラム構成要素の使用における動作、又は不正なデータ若しくは不確定な値を持つオブジェクトの使用における動作であり、この規格が何ら要求を課さない動作。未定義の動作に対して、その状況を無視して予測不可能な結果を返してもよい。」
http://www.kouno.jp/home/c_faq/c11.htmlより引用:
11.33:
実装により定義された(implementation-defined)動作、不定の(unspecified)動作、未定義の(undefined)動作を区別することを世の中では重視するようだ。違いは?
A:
簡潔に説明する。実装により定義された動作とは、どう振る舞うかを実装が選択して、その振る舞いを文書にすることを意味する。不定の動作とは、どう振る舞うかを実装が選択しなければならないが文書にする必要はないことを意味する。未定義とは、本当にどんなことがおこっても不思議ではないことを意味する。どの場合にも規格は、必要条件を課していない。最初の2つの動作について規格は時々ありそうな振る舞いの集合について少し提案している(その集合から選択しなければならないかもしれない)。
.
規格は未定義の動作に直面したときのコンパイラの動作について何も必要条件を設定していないことに注意すること。だからコンパイラは本当に何をしてもいいことになる。プログラムの中に未定義の動作があっても何とかやっていけると考えるのは大変危険である。比較的簡単な例が質問3.2に出てくる。
.
移植性のあるコードを書きたいのなら上の3つの違いを無視することができる。これら3つの動作のどれにも頼らないコードを書こうと思うだろうから。
投稿2015/10/28 11:02
総合スコア6191
0
そのページに十分解説されていると思うのですが、どのあたりがわからないのでしょうか?
一応、JIS規格票も見てみましたが、
3.4.3 未定義の動作(undefined behavior) 可搬性が無い若しくは正しくないプログラム構成要素を使用したときの動作、又は正しくないデータを使用したときの動作で有り、この規格が何ら要求を課さないもの。
3.4.4 未規定の動作(unspecified behavior) この規格が、二つ以上の可能性を提供し、個々の場合にどの可能性を選択するかに関して何ら要求を課さない動作。
となっています。
お書きのページはずっと丁寧で、これ以上の説明は無いと思います。
投稿2015/10/27 13:46
総合スコア84633
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
(数年前の質問ですが、検索の際にトップに出てくるので、メモ的な目的で回答)
コードを組む上での話
コードを組む上であれば、未定義も未規定も避けて実装する必要があります。
どちらも、どのように実行されるかわからない(コンパイラの種類や設定を変えると動かなくなる)
状況が発生します。
未定義
未定義は「明らかに正しくない処理」に対して、 エラーとなったり、無関係な変数が書き換わったり、何が起こるかわからない (=コンパイラが自由に決めてよい)という意味で使われます( 誤解を恐れずに言うならエラーの代わり )
例えば、
- 0除算(例:
int n= 1/0;
) - 配列の範囲外へのアクセス(例:
int n[10]
と宣言されているのにn[11]
の値を取り出す・代入する等) - nullに対してのデリファレンス
等があげられます。
エラーではなく未定義としたのは、エラーとしてしまうと、エラーチェックが必要となり、その結果パフォーマンスが悪くなる(例えば、0除算のチェックであれば、全ての割り算の処理について割る数が0でないか確認する必要がある)のを防ぐためだと考えられます。
未規定
未規定は「文法上正しいが解釈の仕方が複数あるため、どう動作するか解らない」ものに対して使用されます。
例えば、以下の処理
cpp
1int n=0; 2hoge(++n, ++n);
について、1番目の引数も、2番目の引数も処理上エラーは発生しません。
しかし、 1番目の引数と2番目の引数のどちらを先に処理するか は決められていない(未規定)のため、あるコンパイラAでは、hoge(1, 2)
と扱われるかもしれませんし、他のコンパイラBではhoge(2, 1)
と扱われるかもしれません。
投稿2019/09/21 17:28
総合スコア149
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
こんにちは。
私も「未規定」は初めて聞いた言葉ですが、例示を見る限り、未規定は正常、未定義は異常ということと思います。
未規定は振る舞いが規定されていないけど、エラーではないです。つまり、未規定な状態が発生する記述をしてよいです。未規定な状態に頼らなければ良いだけです。
例には見つかりませんでしたが、初期化していない変数の値は未規定の筈です。
未定義は同じく振る舞いが規定されていないけど、エラーになることがあるってことですね。未定義となる記述はするべきではないです。
投稿2015/10/28 10:10
総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。