アカウント名:
パスワード:
最大の欠点かどうかはさておき、問題にしている部分は正確にはC言語の配列操作、あるいはポインタ操作じゃないの?
ポインタが何でもできるから危険なのはたしかだけどね、それを無くしたらCじゃない。
配列の宣言外へアクセスをしてもエラーにならない点がかなり厄介ですよね。範囲外にアクセスしたら例外か、エラーになる事が保障されてれば大分平和になると思うんですけどねぇ。後は、Unicode文字列を正しく扱う為のスキルとか、混在時の取り扱いとかですかね・・・
/* 静的/動的解析ツールがもっと安くなって個人でも気軽に購入可能になるでも可。*/
そんなことをしたら、char a[0];が書けなくなってしまう。
何にどう使うのか場面が想像出来ないですが、実アクセス時に死ねば良いかと。まさか、そのまま代入も何もせずa[1]とかにアクセスする訳じゃないですよね?
# まぁ、C言語でH/Wやら叩きたい向きには不便な足かせだろうなーとは思いますが。
宣言という表現が良くなかったのかもと思い直しました。要は使用します!と宣言してないメモリ領域へのアクセスで安全に死んでくれれば・・・という話でした。でも確かに上記のようなテクニックは宣言ベースだと困りますね。上述パタン(構造体末尾の配列のみ例外として許可)とかもアリだと思いますが。
# mallocとかでOSから取って来るのに限ればOSのガードページが使えるので小細工である程度なんとかなりますが。# スタック領域の自動変数とかが困り物・・・
ふう、あなた、何にも知らないんですね。このテクニック、ほとんどの処理系で通るんですが、規格上は、未定義になります。あと、a[0]はコンパイル時にエラーにする処理系が多数あります。a[1]にすると、かなりの処理系でOKです。もちろん、a[0]をエラーにしても規格に合致した処理系です。
要素数0の配列は古い規格ではコンパイルエラーになりますが、今では正式に取り入れられてます。構造体要素が連続したメモリ上に確保されるという仕様と、&a[n]が a+sizeof(a[0])*n に展開される仕様からは未定義という結論には成り得ません。これが未定義なら、その処理系はCの規格に準拠していない。a[1];にするとsizeofの値がバウンダリの影響を受けるので、それこそ未定義になります。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
最初のバージョンは常に打ち捨てられる。
文字列操作じゃない (スコア:1)
最大の欠点かどうかはさておき、問題にしている部分は正確にはC言語の配列操作、
あるいはポインタ操作じゃないの?
ポインタが何でもできるから危険なのはたしかだけどね、それを無くしたらCじゃない。
Re: (スコア:1)
配列の宣言外へアクセスをしてもエラーにならない点がかなり厄介ですよね。
範囲外にアクセスしたら例外か、エラーになる事が保障されてれば大分平和になると思うんですけどねぇ。
後は、Unicode文字列を正しく扱う為のスキルとか、混在時の取り扱いとかですかね・・・
/*
静的/動的解析ツールがもっと安くなって個人でも気軽に購入可能になるでも可。
*/
Re: (スコア:0)
そんなことをしたら、
char a[0];
が書けなくなってしまう。
Re:文字列操作じゃない (スコア:1)
何にどう使うのか場面が想像出来ないですが、実アクセス時に死ねば良いかと。
まさか、そのまま代入も何もせずa[1]とかにアクセスする訳じゃないですよね?
# まぁ、C言語でH/Wやら叩きたい向きには不便な足かせだろうなーとは思いますが。
Re: (スコア:0)
struct fizz {
size_t length;
char a[0]; /*長さ0の配列メンバーは末尾でのみ使用可能*/
}
void main(void) {
struct fizz *f;
f = (struct fizz*)malloc(100/*←この数値がデータ長になる*/+sizeof(struct fizz));
f->length = 100;
f->a[1]; /*ここはアロケート済みメ
Re:文字列操作じゃない (スコア:1)
宣言という表現が良くなかったのかもと思い直しました。
要は使用します!と宣言してないメモリ領域へのアクセスで安全に死んでくれれば・・・という話でした。
でも確かに上記のようなテクニックは宣言ベースだと困りますね。
上述パタン(構造体末尾の配列のみ例外として許可)とかもアリだと思いますが。
# mallocとかでOSから取って来るのに限ればOSのガードページが使えるので小細工である程度なんとかなりますが。
# スタック領域の自動変数とかが困り物・・・
Re: (スコア:0)
ふう、あなた、何にも知らないんですね。
このテクニック、ほとんどの処理系で通るんですが、規格上は、未定義になります。
あと、a[0]はコンパイル時にエラーにする処理系が多数あります。a[1]にすると、かなりの処理系でOKです。
もちろん、a[0]をエラーにしても規格に合致した処理系です。
Re: (スコア:0)
要素数0の配列は古い規格ではコンパイルエラーになりますが、今では正式に取り入れられてます。
構造体要素が連続したメモリ上に確保されるという仕様と、&a[n]が a+sizeof(a[0])*n に展開される仕様からは未定義という結論には成り得ません。
これが未定義なら、その処理系はCの規格に準拠していない。
a[1];にするとsizeofの値がバウンダリの影響を受けるので、それこそ未定義になります。