C11(n1570)§6.5.8[関係演算子] / 2:
制約
次のいずれかが成立します。
- 両方のオペランドは実数型です; また
- 両方のオペランドは、互換性のあるオブジェクト型の修飾バージョンまたは非修飾バージョンへのポインタです。
(実数型とは、整数型、列挙型、実数浮動小数点型、およびchar
(§6.2.5/ 17)を意味します)
§6.5.9[等式演算子]
制約
次のいずれかが成立します。
- 両方のオペランドの算術型は;
- 両方のオペランドは、互換性のあるタイプの修飾バージョンまたは非修飾バージョンへのポインターです。
- 1つのオペランドはオブジェクト型へのポインターであり、もう1つは修飾または非修飾バージョンの;へのポインターです。
void
また
- 一方のオペランドはポインターで、もう一方はヌルポインター定数です。
§6.5.16.1[簡単な割り当て]/1:
制約
次のいずれかが成立します。
- 左側のオペランドはアトミック、修飾、または非修飾の算術型であり、右側は算術型です。
- 左側のオペランドには、右側の型と互換性のある構造体または共用体型のアトミック、修飾、または非修飾バージョンがあります。
- 左側のオペランドには、アトミック、修飾、または非修飾のポインター型があり、(左オペランドが左辺値変換後に持つ型を考慮すると)両方のオペランドは
、互換性のある型の修飾または非修飾バージョンへのポインターであり、左側が指す型にはすべてがあります。右が指すタイプの修飾子。
- 左側のオペランドには、アトミック、修飾、または非修飾のポインター型があり、(左オペランドが左辺値変換後に持つ型を考慮すると)一方のオペランドはオブジェクト型へのポインターであり、もう一方は修飾または非修飾バージョンへの
ポインター
void
です。 、および左が指す型には、右が指す型のすべての修飾子があります。
- 左側のオペランドはアトミック、修飾、または非修飾のポインターであり、右側はヌル
ポインター定数です。または、左側のオペランドのタイプがアトミック、修飾、または非修飾
_Bool
であり、右側が
ポインターです。
基本的に、3つの式はすべて、式に設定された制約に違反していました。
制約に違反するとはどういう意味ですか?エラー?しかし、制約に違反すると翻訳が失敗するということはどこにもありません。C規格はあまり明確ではないようですが、最も近い解釈は次のようになります。
§4[適合性]/2:
制約または実行時制約の外側に表示される「shall」または「shallnot」要件に違反した場合、動作は定義されません。
しかし、これは制約の外側について話します。および§5.1.1.3[診断]/1:
動作が未定義または実装として明示的に指定されている場合でも、前処理の変換ユニットまたは変換ユニットに構文規則または制約の違反が含まれている場合、準拠する実装は少なくとも1つの診断メッセージ(実装定義の方法で識別される)を生成する必要があります-定義されています。他の状況では、診断メッセージを生成する必要はありません。
したがって、コンパイラは少なくともメッセージを生成する必要があります(gccで確認できます)が、その後に何をすべきかについては述べていません。
この段落の後の例はそれを述べています
例
実装は、翻訳ユニットの診断を発行する必要があります。
char i;
int i;
この国際規格の文言が構成の振る舞いを制約エラーであり、未定義の振る舞いをもたらすと説明している場合、制約エラーは診断されなければならないからです。
および§6.7[宣言]/3は、制約に違反すると未定義の動作が発生することを明示的に言及していません。
したがって、3つの式はすべて未定義の動作であり、診断メッセージが付随していると推測されます。