C11標準ISO/IEC 9899:以下の技術的な合法性
つ保有していなければならない::2011(E)は§6.5.16.1/ 1で、単純な割り当てについては、以下の制約が述べ
- 左のオペランドには、アトミック、修飾、または非修飾の算術型があり、右には 算術型があります。
- 左のオペランドには、アトミック、修飾、または修飾されていないバージョンの構造体または共用体があり、右の型と互換性のある型 があります。
- 左オペランドは、両方のオペランドが互換性のあるタイプの修飾または非修飾バージョンに ポインタであり、タイプは を指摘し、原子修飾、または非修飾ポインタ型を有し、かつ(左オペランドは左辺値変換後だろう タイプを考慮して)左には、右に指し示されているタイプのすべての修飾子があります。
- 左オペランドは、原子修飾、または非修飾ポインタ型を有し、一方のオペランドがオブジェクト型へのポインタ であり、他方はへのポインタである(左のオペランドが左辺値変換後だろう タイプを考慮して) voidの修飾子付きまたは修飾子なしのバージョンであり、左側が指し示す型は、右に を指す型のすべての修飾子を持ちます。
- 左のオペランドは、アトミック、修飾、または非修飾ポインタであり、右はNULL ポインタ定数です。または
- 左のオペランドは、アトミック、修飾、または非修飾のタイプ
_Bool
を持ち、右はポインタです。
私は両側がvoid
異なる互換性のない型へのポインタである場合には興味があります。私が正しく理解していれば、この制約に違反するので、これは少なくともUBを呼び出すべきです。互換性のない型の1つの例は、(6.1.7および6.7.2に従って)int
およびdouble
である必要があります。
したがって、次のプログラムは、違反にする必要があります:
int main(void) {
int a = 17;
double* p;
p = &a;
(void)p;
}
どちらもgccと打ち鳴らすには、「-Wincompatibleポインタ・タイプ」について警告が、(-std=c11 -Wall -Wextra -pedantic
でコンパイル)コンパイルを中止しないでください。
同様に、次のプログラムは "Wint-conversion"警告のみを表示し、コンパイルは正常です。
int main(void) {
int a;
double* p;
p = a;
(void)p;
}
C++から来ているので、いずれかのテストケースでコンパイルするためにキャストが必要になると思いました。いずれかのプログラムが標準法的になる理由はありますか?あるいは、-std=gnu11
の代わりに-std=c11
を明示的に使用して面白いGNU C拡張機能を無効にしても、このコードスタイルをサポートする歴史的な理由は少なくともありますか?厳密な規格準拠のためのチェックを要求すると不適合コードをコンパイルすることを拒否する
いいえ、それはツールチェーンの問題です。私のマシンでは、gccとclangの両方が診断結果を出力します。そうではありません、 '-pendantic'は行く方法ではありません。方法は、プラットフォームを更新することです。 –
GCCは明らかにこれを警告しますが、間違ったCコードのコンパイルを止めるには '-pedantic-errors'が必要です。 – Lundin