質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

4回答

11569閲覧

C言語、未定義と未規定の違い

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

2クリップ

投稿2015/10/27 10:51

「詳説cポインタ」を読んで未規定と未定義の違いがわからなくて、調べてみたのですがネットにも情報が少なく良くわかりません。
http://www.c-lang.org/detail/unspecified_behavior.html
http://www.c-lang.org/detail/undefined_behavior.html
わかりやすく教えていただけないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

質問文中で言及されているページに、既に厳密な説明がありますね。もう少しくだけた説明なら、下記ページ等が参考になるかと思います。

http://www.st.rim.or.jp/~phinloda/cqa/cqa7.htmlより引用:

Q 【未定義】
未定義とは何か。不定と何が違うのか。

未定義とは、その結果どうなるかが、言語仕様として決められていないことを意味します。そして、その結果がどうなっても、その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

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

そのページに十分解説されていると思うのですが、どのあたりがわからないのでしょうか?

一応、JIS規格票も見てみましたが、

3.4.3 未定義の動作(undefined behavior) 可搬性が無い若しくは正しくないプログラム構成要素を使用したときの動作、又は正しくないデータを使用したときの動作で有り、この規格が何ら要求を課さないもの。
3.4.4 未規定の動作(unspecified behavior) この規格が、二つ以上の可能性を提供し、個々の場合にどの可能性を選択するかに関して何ら要求を課さない動作。

となっています。

お書きのページはずっと丁寧で、これ以上の説明は無いと思います。

投稿2015/10/27 13:46

otn

総合スコア84505

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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

whistyun

総合スコア149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/11/09 13:18

「未規定」の方の例が未定義動作になっているものと思われます。 関数の引数呼び出しのコンマは副作用完了点ではないので、「2つの副作用完了点の間で、式の評価によって1つのオブジェクトが2回以上変更された場合」に該当してしまいます。
guest

0

こんにちは。

私も「未規定」は初めて聞いた言葉ですが、例示を見る限り、未規定は正常、未定義は異常ということと思います。

未規定は振る舞いが規定されていないけど、エラーではないです。つまり、未規定な状態が発生する記述をしてよいです。未規定な状態に頼らなければ良いだけです。
例には見つかりませんでしたが、初期化していない変数の値は未規定の筈です。

未定義は同じく振る舞いが規定されていないけど、エラーになることがあるってことですね。未定義となる記述はするべきではないです。

投稿2015/10/28 10:10

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問