未定義、未指定、および実装定義の動作

548
Zolomon 2010-03-08 11:10.

CおよびC ++の未定義の動作とは何ですか?不特定の動作と実装定義の動作はどうですか?それらの違いは何ですか?

8 answers

423
fredoverflow 2010-11-06 00:41.

未定義の振る舞いは、他の言語から来たプログラマーにとって驚くべき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 ++標準には、唯一の投票期間があります。

未定義の動作の他の例には、境界を超えた配列へのアクセス、nullポインターの逆参照、存続期間が終了した後のオブジェクトへのアクセス、またはのような巧妙な式の記述が含まれi++ + ++iます。

C ++標準のセクション1.9では、未定義の振る舞いの危険性の低い2つの兄弟、未定義の振る舞い実装定義の振る舞いについても言及しています。

この国際規格のセマンティック記述は、パラメータ化された非決定論的抽象マシンを定義します。

抽象マシンの特定の側面と操作は、この国際規格で実装定義として説明されています(たとえばsizeof(int))。これらは、抽象マシンのパラメーターを構成します。各実装には、これらの点での特性と動作を説明するドキュメントを含める必要があります。

抽象マシンの他の特定の側面と操作は、この国際規格では指定されていないものとして説明されています(たとえば、関数への引数の評価の順序)。可能な場合、この国際規格は一連の許容可能な動作を定義します。これらは、抽象マシンの非決定論的側面を定義します。

他の特定の操作は、この国際規格では未定義として説明されています(たとえば、nullポインターの逆参照の影響)。[この国際規格は、未定義の動作を含むプログラムの動作に要件を課していません。エンドノート]

具体的には、セクション1.3.24には次のように記載されています。

許容される未定義の動作は、予測できない結果状況を完全に無視することから、環境に特徴的な文書化された方法で翻訳またはプログラムの実行中に動作すること(診断メッセージの発行の有無にかかわらず)、翻訳または実行の終了(発行あり)にまで及びます。診断メッセージの)。

未定義の動作に遭遇するのを避けるために何ができますか?基本的に、あなたは彼らが何について話しているかを知っている著者による良いC ++の本を読まなければなりません。インターネットチュートリアルをねじ込みます。ブルシルトをねじ込みます。

98
AnT 2010-03-08 11:15.

さて、これは基本的に標準からのストレートコピーペーストです

3.4.1 1実装定義の動作不特定の動作。各実装は、選択がどのように行われるかを文書化します。

2例実装定義の動作の例は、符号付き整数が右にシフトされたときの上位ビットの伝搬です。

3.4.3 1移植不可能または誤ったプログラム構成、または誤ったデータを使用した場合の未定義の動作動作。この国際規格は要件を課していません。

2注考えられる未定義の動作は、予測できない結果で状況を完全に無視することから、環境に特徴的な文書化された方法で翻訳またはプログラムの実行中に動作すること(診断メッセージの発行の有無にかかわらず)、翻訳または実行の終了(診断メッセージの発行)。

3例未定義の動作の例は、整数オーバーフローの動作です。

3.4.4 1不特定の動作不特定の値の使用、またはこの国際規格が2つ以上の可能性を提供し、どのような場合でも選択される要件を課さないその他の動作

2例不特定の動作の例は、関数への引数が評価される順序です。

60
AraK 2010-03-08 11:28.

おそらく、簡単な言い回しは、標準の厳密な定義よりも理解しやすいかもしれません。

実装定義の動作
この言語では、データ型があると言われています。コンパイラベンダーは、使用するサイズを指定し、実行した内容のドキュメントを提供します。

未定義の振る舞い
あなたは何か間違ったことをしています。たとえば、にint収まらない非常に大きな値がありcharます。その値をどのように入れますcharか?実際には方法はありません!何が起こる可能性もありますが、最も賢明なことは、そのintの最初のバイトを取得してchar。に入れることです。最初のバイトを割り当てるためにそれを行うのは間違っていますが、それは内部で起こることです。

不特定の動作
これら2つの機能のどちらが最初に実行されますか?

void fun(int n, int m);

int fun1()
{
  cout << "fun1";
  return 1;
}
int fun2()
{
  cout << "fun2";
  return 2;
}
...
fun(fun1(), fun2()); // which one is executed first?

言語は、左から右または右から左の評価を指定していません!したがって、不特定の動作が未定義の動作になる場合とそうでない場合がありますが、プログラムが不特定の動作を生成することはありません。


@eSKayあなたの質問はもっと明確にするために答えを編集する価値があると思います:)

fun(fun1(), fun2());動作は「実装が定義されている」のではないのですか?結局のところ、コンパイラはどちらかのコースを選択する必要がありますか?

実装定義と未指定の違いは、コンパイラーが最初のケースで動作を選択することになっているが、2番目のケースでは選択する必要がないことです。たとえば、実装には、の定義が1つだけ必要ですsizeof(int)。したがって、sizeof(int)プログラムの一部で4、他の部分で8であるとは言えません。コンパイラがOKと言うことができる不特定の動作とは異なり、これらの引数を左から右に評価し、次の関数の引数を右から左に評価します。同じプログラムで発生する可能性があるため、unspecifiedと呼ばれます。実際、指定されていない動作のいくつかが指定されていれば、C ++はより簡単になりました。そのためのStroustrup博士の答えをここで見てください:

コンパイラにこの自由を与えることと「通常の左から右への評価」を要求することとの間の違いは重要である可能性があると主張されています。私は確信が持てませんが、自由を利用する無数のコンパイラーとその自由を熱心に擁護する人々がいると、変更は難しく、CおよびC ++の世界の遠い隅に浸透するのに数十年かかる可能性があります。すべてのコンパイラが++ i + i ++などのコードに対して警告するわけではないことに失望しています。同様に、引数の評価の順序は指定されていません。

IMOの「もの」が多すぎて、未定義、未指定、実装定義などが残されています。ただし、これは簡単に言うことができ、例を示すこともできますが、修正するのは困難です。また、ほとんどの問題を回避して移植可能なコードを作成することはそれほど難しいことではないことにも注意してください。

27
Johannes Schaub - litb 2013-01-24 08:46.

公式のC根拠文書から

未指定の動作、未定義の動作、および実装定義の動作という用語は、標準で完全に記述されていない、または完全に記述できないプロパティを持つプログラムを作成した結果を分類するために使用されます。この分類を採用する目的は、標準への適合性のキャッシュを削除することなく、実装の品質を市場で積極的に発揮できるようにするだけでなく、特定の人気のある拡張機能を可能にする実装間の特定の多様性を可能にすることです。標準の付録Fは、これら3つのカテゴリのいずれかに分類される動作をカタログ化しています。

不特定の動作は、実装者にプログラムの翻訳にある程度の自由度を与えます。この許容範囲は、プログラムの翻訳に失敗するまでは拡張されません。

未定義の動作は、診断が難しい特定のプログラムエラーをキャッチしないように実装者にライセンスを与えます。また、準拠する可能性のある言語拡張の領域を識別します。実装者は、公式に定義されていない動作の定義を提供することにより、言語を拡張できます。

実装定義の動作により、実装者は適切なアプローチを自由に選択できますが、この選択についてユーザーに説明する必要があります。実装定義として指定された動作は、一般に、ユーザーが実装定義に基づいて意味のあるコーディング決定を行うことができる動作です。実装者は、実装定義をどの程度広範にするかを決定する際に、この基準を念頭に置く必要があります。不特定の動作と同様に、実装で定義された動作を含むソースの変換に失敗するだけでは、適切な対応にはなりません。

10
Anders Abel 2010-03-08 11:18.

未定義の振る舞いと不特定の振る舞いについては、簡単に説明しています。

彼らの最終的な要約:

要約すると、不特定の動作は、ソフトウェアがポータブルである必要がない限り、通常は心配する必要はありません。逆に、未定義の動作は常に望ましくなく、発生してはなりません。

8
supercat 2015-04-16 17:32.

歴史的に、実装定義の動作と未定義の動作はどちらも、標準の作成者が、品質の実装を作成する人々が判断を使用して、で実行されている目的のアプリケーションフィールドのプログラムに役立つ動作保証がある場合はそれを決定することを期待する状況を表しています。意図されたターゲット。ハイエンドの数値計算コードのニーズは、ローレベルのシステムコードのニーズとはまったく異なり、UBとIDBの両方により、コンパイラの作成者はこれらのさまざまなニーズに柔軟に対応できます。どちらのカテゴリーも、実装が特定の目的に、あるいはあらゆる目的にさえ役立つ方法で動作することを義務付けていません。ただし、特定の目的に適していると主張する品質の実装は、規格で要求されているかどうかに関係なく、そのような目的に適した方法で動作する必要があります。

実装定義の動作と未定義の動作の唯一の違いは、前者では、実装で何もできない場合でも、実装が一貫した動作を定義して文書化する必要があることです。それらの間の境界線は、実装が動作を定義するのに一般的に役立つかどうかではなく(コンパイラの作成者は、標準で要求されているかどうかに関係なく、実用的な場合に有用な動作を定義する必要があります)、動作の定義が同時にコストがかかる実装があるかどうかです。と役に立たない。そのような実装が存在する可能性があるという判断は、他のプラットフォームで定義された動作をサポートすることの有用性についての判断を意味するものではありません。

残念ながら、1990年代半ば以降、コンパイラの作成者は、動作の義務がないことを、動作の保証が不可欠なアプリケーション分野でも、実質的にコストがかからないシステムでも、コストに見合わないという判断として解釈し始めています。UBを合理的な判断を行使するための招待として扱う代わりに、コンパイラの作成者はUBをそうしない言い訳として扱い始めました。

たとえば、次のコードがあるとします。

int scaled_velocity(int v, unsigned char pow)
{
  if (v > 250)
    v = 250;
  if (v < -250)
    v = -250;
  return v << pow;
}

2の補数の実装では、正か負v << powvに関係なく、式を2の補数シフトとして扱うために労力を費やす必要はありません。

しかし、今日のコンパイラ作成者の間で好まれる哲学vは、プログラムが未定義の振る舞いを行う場合にのみ負になる可能性があるため、プログラムにの負の範囲をクリップさせる理由はないことを示唆していますv。負の値の左シフトは、重要なすべてのコンパイラでサポートされていましたが、既存のコードの多くはその動作に依存していますが、現代の哲学では、標準では左シフトの負の値はUBであると解釈されます。コンパイラの作成者はそれを無視してかまいません。

7
Suraj K Thomas 2015-03-17 21:11.

実装の定義-

実装者は、十分に文書化されている必要があり、標準は選択肢を提供しますが、必ずコンパイルすることを望んでいます

詳細不明-

実装定義と同じですが、文書化されていません

未定義-

何かが起こるかもしれません、それの世話をしてください。

6
4pie0 2014-05-11 02:35.

C ++標準n3337 § 1.3.10処理系定義の動作

実装に依存し、各実装が文書化する、整形式のプログラム構成と正しいデータの動作

C ++標準は、一部の構成に特定の動作を課さない場合がありますが、代わりに、特定の実装(ライブラリのバージョン)によって特定の明確に定義された動作を選択して記述する必要があると述べています。そのため、Standardで説明されていなくても、ユーザーはプログラムがどのように動作するかを正確に知ることができます。


C ++標準n3337 § 1.3.24未定義の動作

この国際規格が要件を課していない動作[注:この国際規格が動作の明示的な定義を省略している場合、またはプログラムが誤った構成または誤ったデータを使用している場合、未定義の動作が予想される場合があります。許容される未定義の動作は、予測できない結果で状況を完全に無視することから、環境に特徴的な文書化された方法で翻訳またはプログラムの実行中に動作すること(診断メッセージの発行の有無にかかわらず)、翻訳または実行の終了(発行あり)にまで及びます。診断メッセージの)。多くの誤ったプログラム構成は、未定義の動作を引き起こしません。それらは診断される必要があります。—エンドノート]

プログラムがC ++標準に従って定義されていない構成に遭遇すると、やりたいことを何でも実行できます(おそらく、私に電子メールを送信するか、あなたに電子メールを送信するか、コードを完全に無視します)。


C ++標準n3337 § 1.3.25 、不特定の行動

実装に依存する、整形式のプログラム構成と正しいデータの動作[注:実装は、発生する動作を文書化する必要はありません。可能な動作の範囲は、通常、この国際規格によって示されます。—エンドノート]

C ++標準は、一部の構造に特定の動作を課しませんが、代わりに、特定の実装(ライブラリのバージョン)によって特定の明確に定義された動作を選択する必要があると述べています(ボットは説明する必要はありません)。したがって、説明が提供されていない場合、ユーザーはプログラムがどのように動作するかを正確に知ることが難しい場合があります。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

今週のコミックコンですべての素晴らしいものに追いつく方法

今週のコミックコンですべての素晴らしいものに追いつく方法

サンディエゴコミックコンは今週開幕し、オタクのアナウンス、ポスター、予告編、お気に入りの番組や映画のからかいでいっぱいになります。SDCCは、コンベンションフロア全体の多くのパネルで行われているため、すべてに対応するのは難しい場合があります。

Googleの9千万ドルの和解はアプリ開発者にとってもGoogleにとっても勝利ですか?

Googleの9千万ドルの和解はアプリ開発者にとってもGoogleにとっても勝利ですか?

小さなアプリ開発者は金曜日に発表された法的な和解でグーグルから9千万ドルをこじ開けた。アップルとの同様の合意に続いて熱くなった。金曜日のブログ投稿で、Googleは、Androidメーカーが市場での優位性を悪用してPlayストア経由でのアプリ内購入に対して30%の料金を不当に請求したと主張するアプリ開発者との訴訟を解決するために、9千万ドルを支払うことに合意したと述べました。

RadioShackのTwitterはハッキングされていませんでした、それはただの暗号のサクラです

RadioShackのTwitterはハッキングされていませんでした、それはただの暗号のサクラです

今週、RadioShackのTwitterアカウントは、奇妙なものから完全にひどいものになりました。短い順序で、会社のフィード全体が、バイブレーター、「ビッグティット」(スペルミス)、有名人やその他の企業アカウントを荒らしているツイートなど、NSFW素材の真の山になりました。

ヒッグス粒子から10年後、物理学にとって次の大きなものは何ですか?

ヒッグス粒子から10年後、物理学にとって次の大きなものは何ですか?

大型ハドロン衝突型加速器のトンネル内にあるコンパクトミュオンソレノイド(CMS)検出器。2012年7月4日、CERNの科学者たちは、1960年代に最初に提案された素粒子であるヒッグス粒子の観測を確認しました。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

Un breve viaje espacial sobre conceptualizar el diseño

Complicarse la vida, mezclar churros con meninas (nada de ovejas) y encontrar valor en un trastero que adquiriste en una puja.

Un breve viaje espacial sobre conceptualizar el diseño

Bien. Hay un momento en toda salida al espacio exterior en el que de la tensión, la velocidad y las altas temperaturas derivadas del cruce de estratosfera a ionosfera se pasa a un momento de súbita calma, donde se despliega la vista completa del paisaje espacial que nos rodea.

Seguindo Todos os Protocolos (2022), de Fábio Leal

Seguindo Todos os Protocolos (2022), de Fábio Leal

Chico quer transar. Até aí, tudo bem.

多元宇宙—Junø

多元宇宙—Junø

チェーン間アカウントがJunoに登場します。異なるブロックチェーン間でスマートコントラクトの構成可能性と真の相互運用性を提供します。

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「​​ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。

Language