アカウント名:
パスワード:
C/C++で、他の言語ならコンパイルエラーになるとか例外投げて死ぬとか規定されているべき場面で「未定義」になること。
次みたいな、決めればいいのにってのも未定義だしな。。。 a[i] = i++;
どう決めるべきなの? (ありがちな反応)
(そしてどう決めるべきかで揉めるのもありがち)
コンパイルエラーでいいだろ。どうせ書いてはいけないコードなんだし
実行時に決まるから無理。検出可能な単純なパターンもあるけど、中途半端に検出しても事故の元。
int x = 0, y = 0;int *i, *j;
i = &x;if(hoge){ j = &y;}else{ j = i;}
a[*i] = (*j)++;
だと、実行時のhogeの値によって、未定義動作になるかならないかが変わる。
ちなみに、このプログラムは、「書いてもいい」けど、「実行時にhoge==0となってはいけない」と言うグレーゾーンに位置する。
これ以外の部分の動作により、この部分にさしかかるタイミングではhogeが絶対に0ではないプログラムならOK。この部分にさしかかったときにhogeが0になっている可能性のあるプログラムならNG。
> 実行時に決まるから無理。
静的に検出できるものは検出すればいい。実際clangにはそのようなオプションもある。clang以外でも、たとえば手元のVisual C++ 2013は
int i = 1 / 0;
というコードをコンパイルエラーにしたけど、これは事故の元だからやるなと?
> 検出可能な単純なパターンもあるけど、中途半端に検出しても事故の元。
どんな事故の元になるの? どんな事故が起きるとしても、それは現行の規格でも事故になるものしかありえないはずだけど。
実行時については、未定義を許容することで可能になる最適化があるから仕方ない(今さらどうしようもない)けど。
> i = &x;
静的に検出できるものは検出すればいい。
仕様で未定義だと言っているのは、つまりコンパイラーで静的に検出できるものはコンパイルエラーにしてもいいよと言っているわけで、あなたが望む通りの仕様になっているんだけど。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
吾輩はリファレンスである。名前はまだ無い -- perlの中の人
未定義動作 (スコア:0)
C/C++で、他の言語ならコンパイルエラーになるとか例外投げて死ぬとか規定されているべき場面で「未定義」になること。
Re: (スコア:0)
次みたいな、決めればいいのにってのも未定義だしな。。。
a[i] = i++;
Re: (スコア:2)
どう決めるべきなの? (ありがちな反応)
(そしてどう決めるべきかで揉めるのもありがち)
Re: (スコア:0)
コンパイルエラーでいいだろ。どうせ書いてはいけないコードなんだし
Re: (スコア:1)
実行時に決まるから無理。検出可能な単純なパターンもあるけど、中途半端に検出しても事故の元。
int x = 0, y = 0;
int *i, *j;
i = &x;
if(hoge){
j = &y;
}else{
j = i;
}
a[*i] = (*j)++;
だと、実行時のhogeの値によって、未定義動作になるかならないかが変わる。
ちなみに、このプログラムは、「書いてもいい」けど、「実行時にhoge==0となってはいけない」と言うグレーゾーンに位置する。
これ以外の部分の動作により、この部分にさしかかるタイミングではhogeが絶対に0ではないプログラムならOK。
この部分にさしかかったときにhogeが0になっている可能性のあるプログラムならNG。
Re: (スコア:0)
> 実行時に決まるから無理。
静的に検出できるものは検出すればいい。実際clangにはそのようなオプションもある。clang以外でも、たとえば手元のVisual C++ 2013は
int i = 1 / 0;
というコードをコンパイルエラーにしたけど、これは事故の元だからやるなと?
> 検出可能な単純なパターンもあるけど、中途半端に検出しても事故の元。
どんな事故の元になるの? どんな事故が起きるとしても、それは現行の規格でも事故になるものしかありえないはずだけど。
実行時については、未定義を許容することで可能になる最適化があるから仕方ない(今さらどうしようもない)けど。
> i = &x;
Re:未定義動作 (スコア:2)
仕様で未定義だと言っているのは、つまりコンパイラーで静的に検出できるものはコンパイルエラーにしてもいいよと言っているわけで、あなたが望む通りの仕様になっているんだけど。