アカウント名:
パスワード:
あまりメモリサイズを気にしなくてよいとか、メモリなんて腐るほどあるわいとか、そういう世界では構造体の配列を使うのが正解。
ところが、「メモリの1bitは血の一滴」などという世界では構造体は怖くて使えない。特に今回は構造体の要素が5個…つまり 2^n の数ではない個数存在する。メモリがキツキツである事をしらないコンパイラは、alignment をきれいにするために:
typedef struct { int temperature; int humidity; int pressure; int wind_direction; int wind_speed;} weather_data_t;
を
typed
そういう世界で使うコンパイラは、境界合せをするのだろうか。
word-aligneという意味なら、普通は境界合わせしますよ。構造体のメンバにintが居ればintに, long longが居ればlonglongにというように。詰める必要があるなら、 __attribute__((packed))とか __packedとかで修飾。問題は標準がなくコンパイラに合わせる必要があること。
指示できないコンパイラ(あるいは指示できるのだが、コンパイラの我が強くて言う事を聞かない場合)
は、この世界では使い物にならないでしょう。
この世界では使い物にならないでしょう。
それが必ずしもその一言で消失してくれない辺りが鬱陶しい。
「ポインタ動かす所は別にすればいいじゃん」攻撃はよくある。もちろん、山盛りのバグ付きで。
最も頭痛がするのは、通信ライブラリ周りで、little endian を big endian に直すのに構造体に値を入れる過程で htonl(3)とかを呼べばいい、と思い込んでいるコードが絡んでくる場合で…padding だけでも結構頭痛が…
# だれか教えてくれ。Cの構造体のエレメントのメモリ展開時の順序は本当に保証されているのか??
どういう場面?書き方によってはバッファから読むところで例外が出る事はあるけど、(int境界に合わせてある普通の)構造体特有の問題はあるのかな。
プロトコルヘッダーをバイト列に変換したり、逆にバイト列をプロトコルヘッダーの構造体に直す所。
ソケット周りの実装を読むと、途中で構造体へのポインタがバイト列へのポインタにすり変わったり、その逆が起こったりしているものが多い。大昔のコードが padding とかを一切しなかったので、ポインタのすり替えでできたのだが、その「伝統」が受け継がれてしまっている。
> # だれか教えてくれ。Cの構造体のエレメントのメモリ展開時の順序は本当に保証されているのか??http://portable-c.jugem.jp/?eid=17 [jugem.jp]JIS X 3010:2003を実際に読んで裏をとるべきだが、とりあえずググッた結果を鵜呑みにする限りでは保証されているらしい。# コンパイラが規格準拠でない可能性まで考慮してるなら知らんとしか
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
計算機科学者とは、壊れていないものを修理する人々のことである
それはどういう環境でそのコードを動かしたいのか依存 (スコア:1)
あまりメモリサイズを気にしなくてよいとか、メモリなんて腐るほどあるわいとか、そういう世界では構造体の配列を使うのが正解。
ところが、「メモリの1bitは血の一滴」などという世界では構造体は怖くて使えない。特に今回は構造体の要素が5個…つまり 2^n の数ではない個数存在する。
メモリがキツキツである事をしらないコンパイラは、alignment をきれいにするために:
を
fjの教祖様
Re: (スコア:2)
そういう世界で使うコンパイラは、境界合せをするのだろうか。
Re: (スコア:0)
そういう世界で使うコンパイラは、境界合せをするのだろうか。
word-aligneという意味なら、普通は境界合わせしますよ。
構造体のメンバにintが居ればintに, long longが居ればlonglongにというように。
詰める必要があるなら、 __attribute__((packed))とか __packedとかで修飾。問題は標準がなくコンパイラに合わせる必要があること。
は、この世界では使い物にならないでしょう。
Re:それはどういう環境でそのコードを動かしたいのか依存 (スコア:1)
それが必ずしもその一言で消失してくれない辺りが鬱陶しい。
「ポインタ動かす所は別にすればいいじゃん」
攻撃はよくある。もちろん、山盛りのバグ付きで。
最も頭痛がするのは、通信ライブラリ周りで、little endian を big endian に直すのに構造体に値を入れる過程で htonl(3)とかを呼べばいい、と思い込んでいるコードが絡んでくる場合で…padding だけでも結構頭痛が…
# だれか教えてくれ。Cの構造体のエレメントのメモリ展開時の順序は本当に保証されているのか??
fjの教祖様
Re:それはどういう環境でそのコードを動かしたいのか依存 (スコア:2)
どういう場面?
書き方によってはバッファから読むところで例外が出る事はあるけど、(int境界に合わせてある普通の)構造体特有の問題はあるのかな。
Re:それはどういう環境でそのコードを動かしたいのか依存 (スコア:1)
プロトコルヘッダーをバイト列に変換したり、逆にバイト列をプロトコルヘッダーの構造体に直す所。
ソケット周りの実装を読むと、途中で構造体へのポインタがバイト列へのポインタにすり変わったり、その逆が起こったりしているものが多い。
大昔のコードが padding とかを一切しなかったので、ポインタのすり替えでできたのだが、その「伝統」が受け継がれてしまっている。
fjの教祖様
Re: (スコア:0)
> # だれか教えてくれ。Cの構造体のエレメントのメモリ展開時の順序は本当に保証されているのか??
http://portable-c.jugem.jp/?eid=17 [jugem.jp]
JIS X 3010:2003を実際に読んで裏をとるべきだが、とりあえずググッた結果を鵜呑みにする限りでは保証されているらしい。
# コンパイラが規格準拠でない可能性まで考慮してるなら知らんとしか