web-dev-qa-db-ja.com

標準Cの制約は何ですか?

C標準は制約について話します、e。 g。 ISO/IEC 9899:201x用語を定義します

制約
言語要素の説明を解釈するための構文的または意味的な制限

そして章で言う適合性

制約またはランタイム制約の外側に表示される「shall」または「shallnot」要件に違反した場合、動作は定義されません。

章で環境、サブセクション診断それは言われています

動作が未定義または実装として明示的に指定されている場合でも、前処理の変換ユニットまたは変換ユニットに構文規則または制約の違反が含まれている場合、準拠する実装は少なくとも1つの診断メッセージ(実装定義の方法で識別)を生成する必要があります-定義されています。

したがって、Cの制約は何かを知ることが重要です。たとえば、コンパイラの作成者が診断が必要な時期を判断したり、Cプログラマーが未定義の動作だけでなく診断が予想される場合などです。
現在、標準ドキュメント全体にConstraintsというタイトルのセクションがありますが、constraintという用語が正確に何をカバーしているのかについて明確な表現を見つけることができません。標準。

  • Constraintsというタイトルのセクションに表示されるすべての制約はありますか?
  • それらのセクションの外で述べられているすべての要件は制約ではありませんか?
  • 私が見逃した規格に制約の包括的な説明はありますか?
27
Armali

制約は、「制約」というタイトルのセクションに表示されるすべてのものですか?

N1570 3.8(違反したときにコンパイル時の診断メッセージを発行するために適合実装を必要とするプログラムに課せられた制限)の意味では、私はそう思います。

それらのセクションの外で述べられているすべての要件は制約ではありませんか?

3.8の意味では、私はそう思いますが、より循環的な理由で:標準の構造はかなり形式的です。該当する場合は常に、明示的なConstraintsセクションがあるようです。したがって、定義による制約セクションにないものは3.8の意味での制約ではないことを理解しています。
セクションの外側にいくつかの「shall」句があります制約完全にコンパイル時に強制可能と思われるセクション。以下にいくつかの例を示します。それらはしばしば隣接するセマンティクスセクションにあります。一般的なケースでコンパイル時の検出を妨げる微妙な点が欠落している可能性があります(診断を必須にすることができないため)、またはおそらく標準が完全に一貫していません。しかし、コンパイラは違反しているプログラムを単純に翻訳できると思います。正確にはbecause要件はConstraintsセクションにありません。

私が見逃した規格に制約の包括的な説明はありますか?

私は3.8があなたが得るすべてだと思います。私は以下の用語を調べて、定義が不十分であることに同意します。


私はそれを見つけるために標準をより深く調べました。これが私の研究です。

用語制約

基本から始めましょう。あなたが引用する3.8の「制約」の定義は、少なくとも文脈がなければ、驚くほど理解するのが難しいです(「言語要素の説明が解釈される構文的または意味的な制限」)。 「制限」と「制約」は同義語であるため、言い換えてもあまり追加されません。そして「言語要素の説明」とはどういう意味ですか?博覧会はいくつかの意味を持つ言葉です。 "主に情報を伝えることを目的とした文章またはスピーチ" from Dictionary.com を取り上げて、それらが標準を意味すると仮定しましょう。つまり、基本的に、この標準のconstraintは、この標準で述べられていることの制約であることを意味します。うわー、私はそれを推測していなかっただろう。

制約 3.8による

実用的には、標準の実際のConstraintsセクションを調べるだけで、適合に課せられたコンパイル時間の制限がリストされていることがわかりますprogramsコンパイル時にチェックできるのはコンパイル時の制約のみであるため、これは理にかなっています。これらの追加の制限は、C構文で表現できない制限です。1

外部の制約制約セクション

Constraintsセクション以外での「shall」のほとんどの使用は、適合に制限を課しますimplementation例:"静的ストレージ期間を持つすべてのオブジェクトは、プログラムの起動前に初期化(初期値に設定)する必要があります"、適合実装のジョブ。

ただし、Constraintsセクションの外側のprogram(実装ではない)に制限を課す「shall」句がいくつかあります。私は、ほとんどが3.18で述べた「ライブラリ関数を呼び出すときのプログラムの実行時制約[...]」と同じカテゴリに分類されると主張します。これらは、コンパイル時に一般的に検出できない実行時の制約のようです(そのため、診断を必須にすることはできません)。

ここにいくつかの例があります。

6.5/7では、n1570は、議論の多いエイリアシングルールについて詳しく説明しています。

オブジェクトの格納値には、次のいずれかのタイプの左辺値式によってのみアクセスできます。

  • オブジェクトの有効タイプと互換性のあるタイプ
  • オブジェクトの有効なタイプと互換性のあるタイプの修飾バージョン、[...]

6.5.16.1では、「単純な割り当て」:

オブジェクトに格納されている値が、最初のオブジェクトの格納と何らかの方法で重なり合う別のオブジェクトから読み取られる場合、重なりは正確である必要があります[..]。」

他の例は、ポインタ演算(6.5.6/8)に関するものです。

ShallConstraintsセクションに含まれる可能性のある句

しかし、コンパイル時に違反を検出できるはずの他のshall句があります。それらがそれぞれの制約セクションに表示されていたら、私は瞬きしなかっただろう。

  • 6.6/6、"整数定数式のキャスト演算子は、算術型のみを整数型に変換するものとします"(「セマンティクス」の下)。定数とキャストのタイプを検出できない場合、コンパイル時に何を検出できますか?
  • 6.7/7、"オブジェクトの識別子がリンケージなしで宣言されている場合、オブジェクトのタイプはその宣言子の終わりまでに完了する必要があります"(「セマンティクス」の下)。私には、コードのある時点で型が完全であるかどうかを検出するための基本的なコンパイラタスクのようです。しかしもちろん、私はCコンパイラを書いたことがありません。

さらにいくつかの例があります。しかし、私が言ったように、違反を診断するために実装は必要ないと思います。コンパイラをこっそり通り抜けることができた違反プログラムは、単に未定義の動作を公開します。


1 たとえば、構文が型を処理しないことを理解しています。一般的な「式」しかありません。したがって、すべての演算子には、その引数の許容されるタイプを詳述するConstraintsセクションがあります。シフト演算子の例:"各オペランドは整数型でなければなりません。" floatのビットをシフトしようとしているプログラムはこの制約に違反しており、実装は診断を発行する必要があります。
9

C委員会は、 欠陥レポート#0 への応答でこの問題に対処しました。その欠陥レポートの質問は次のとおりです。

制約というラベルの付いたセクションの外でステートメントが発生した場合でも、標準の「shall」および「shall not」ステートメントのすべての違反を診断するには、準拠する実装が必要ですか?

その欠陥レポートの作成者は、標準の言語を解釈するためのいくつかの可能な代替方法を提案しました。彼がリストした2番目の選択肢は(部分的に)言った:

構文規則は、標準の構文セクションにリストされている項目です。 制約は、標準の制約セクションにリストされている項目です。

委員会の回答の一部は次のとおりです。

提案された解釈#2は正しいものです。

私はそれがあなたの質問をかなり完全にカバーしていると信じていますが、あなたの質問への答えをより直接的に述べるためだけです:

  • 制約は、「制約」というタイトルのセクションに表示されるすべてのものですか?
  • それらのセクションの外で述べられているすべての要件は制約ではありませんか?

「制約」は、「制約」と明示的にマークされたセクションに記載されている要件です。そのようなセクションの外で述べられている要件は、制約ではありません。

  • 私が見逃した規格の制約の包括的な説明はありますか?

少なくとも私が知る限り、標準自体には、制約であるかどうかについてのより具体的なステートメントは含まれていませんが、リンクされた欠陥レポートには含まれています。

7
Jerry Coffin

制約は、「制約」というタイトルのセクションに表示されるすべてのものですか?

ほとんどがそうであるように見えます(そうでない場合もあります、fx:制約セクションの1つで「インクリメントは1を加算することと同等である」と述べられています)。

それらのセクションの外で述べられているすべての要件は制約ではありませんか?

私はそれらのセクションの外に「制約」を見たことがありません。

私が見逃した規格の制約の包括的な説明はありますか?

おそらくそうではないでしょう、もしそのような権威があれば、それは標準にあり、おそらく「制約」セクションになるでしょう(そしてこれらはすべて「制約」であると明示的に述べられています)。

私の解釈では、第3章は、定義された用語のすべての使用がそのセクションで定義された意味を持つように解釈されるべきであるということです。特に「制約」という用語が使用されている場合は常に、最初の引用に従って理解する必要があります。

2番目の見積もりも例外ではありません。 「制約」という用語の定義では、制約が明示的に制約と呼ばれる必要はないことに注意してください。これは、それがそのような制限であるかどうかをチェックすることによって、それが「制約」であるかどうかを判断する必要があることを意味します。

しかし、明示的にそのように呼ばれることなく、そのような制限と見なされる可能性のある「すべき」と「すべきでない」の例はかなりあるようです。これにより、すべてのオカレンスが実装の特定の動作を義務付けまたは禁止することになります。これらが満たされない場合、動作は定義されていない可能性があります(実装を使用していないため)。 t規格に準拠)。

「制約」の定義に当てはまるものはすべて「制約」セクションの下で発生しているように見え、「制約」セクションのすべては「制約」であるように見えます。

2
skyking

要件エンジニアリングの私の仕事では、「制約」と「要件」という言葉の範囲は異なります。標準にとっても、それらを明示的に定義することが重要です。標準で「制約」という単語を検索したところ、次の結論が導き出される可能性があります。

制約は、標準のセクションで説明されている動作の入力(事前条件)または出力(事後条件)のいずれかの制限です。入力の場合、入力は制約に準拠する必要があることを意味します(たとえば、argcは正でなければなりません)。出力の場合、明確に定義された入力(その前提条件)を持つためには、標準の後続のユニットの制約を満たす必要があることを意味します。

要件は、標準のセクションの動作の仕様の一部です。 「しなければならない」は、何が必要かについての前向きな説明です。 「してはならない」は一般に制限ですが、制約ではありません。出力の制約を満たすことに参加する場合があります。

制約と要件は、「外部インターフェース」(制約)および「システムの動作/処理」(要件)と見なすことができます。

Shallは一般的に要件を示します(したがって、「shall」のないフレーズは要件ではありません)。制約で使用される「Shall」は、入力または出力を定義するために使用されるか(たとえば、argcは正である必要があります)、制約の検証に関する動作を指定するために使用されます(たとえば、「...診断メッセージを表示する」)。

厳密に言えば、入力制約を検証する動作を指定する際に使用される「shall」は、制約セクション(インターフェース仕様にリストされるべきではない)ではなく、処理セクション(動作セクション)にリストされるべきです。

出力は仕様に準拠している必要があるため、出力制約の検証はできないことに注意してください。それらが入力制約内にある場合、次のuitのみがそれらの制約をチェックできます。

これは個人的な見解かもしれませんが、標準でのこれらの単語の使用法に適合しているようです。

1
Paul Ogilvie

Constraintsというタイトルのセクションに表示されるすべての制約はありますか?

はい。標準で言及されているすべての構文上および意味上の制限は制約です。

たとえば、定数式(C11-6.6/3)の制約:

定数式には、評価されない部分式に含まれている場合を除き、代入、インクリメント、デクリメント、関数呼び出し、またはコンマ演算子を含めないでください。115)

したがって、定数式

3 = 5;
10++;

制約違反を示しています。

この場合、shall要件とconstraintの両方に違反していることに注意してください。

それらのセクションの外で述べられているすべての要件は制約ではありませんか?

標準準拠のCの場合、はい。整数定数式(C11-6.6/6)のshall要件:

整数定数式117)shall整数型[...]

たとえば、非可変長配列のサイズには整数定数式が必要です。したがって、

int arr[5+1.5];

shall要件に違反しています。式のタイプ5+1.5は整数型ではありません。このshall要件は制約外です。

shall要件も制約になる可能性があることに注意してください。

1
haccks

制約

言語要素の説明が解釈される構文的または意味的な制限

これは、c標準によって設定されたプログラムロジックまたは構文に対するすべての明示的な制限が制約であることを意味します。これには、構文上の制約(たとえば、ブロックは;で終了する必要があります)と意味上の制約(たとえば、初期化する前に変数を使用しないでください)、基本的に構文的(表記法)または意味論的(正しい表記法)許可されていない、または許可されていないものとして定義されている(未定義の動作)。

それらのセクションの外で述べられているすべての要件は制約ではありませんか?

C言語でのプログラミングに対するすべての明示的な要件は、構文的または意味的な制約のいずれかに該当すると思います。

私が見逃した規格の制約の包括的な説明はありますか?

私の知る限りではありません。

0
Magisch