2008-01-15

C++で天啓を得る

 前回、テンプレートメタプログラミングを使いて、アラインメントの問題を直したり。さて今日、暇な午後を満足したりて、半ば眠りかけたるに、たちまちにして天啓を得る。すなわち、「もっと簡単な方法がある」と。  前回のコードはこうだった。
class Bullet { BulletHolder * ptr ; char buf[size] ; //ほかにメンバなど } ;
 コレだから問題なのだ。このようにしてしまえばよい。
class Bullet { struct POD { char buf[size] ;// ポインタのサイズに合わせて適切にアラインメントされているサイズ BulletHolder * ptr ;//何もしなくても、最初から適切にアラインメントされている } data ; //ほかにメンバなど } ;
 このようにすれば、最初から何もする必要がない。気をつけるのは、最初のバッファのサイズだけだ。このバッファの上に、コンパイル時には決定できないアラインメントのオブジェクトが構築されるので、コンパイラには任せられない。ポインタのサイズが4バイトで、バッファの上に構築されるオブジェクトが4バイトアラインメントまでの場合は、4の倍数にしておけばよい。バッファの上に構築されるオブジェクトが8バイトアラインメントまでの場合は、8の倍数に4を足しておけばよい。  ただ、このコードは完璧にアラインメントできるのだろうか。たとえば将来、ポインタのサイズが32バイトになった場合、このコードを32バイトコードにコンパイルしなおしたとき、ポインタのサイズは、まあ4バイトか8バイトだろうと信じている、現在の私のコードは、適切なアラインメントではなくなる。コンパイル時に計算しようにも、取りうる最大のアラインメントの定数をどこかに定義しておかなければ、計算しようがない。  そう考えてみると、Boost.type_traitsの、type_with_alignmentの実装が、なかなか興味深い。結局は総当りになるのか。  

No comments: