いろきゅうの(元)はてなダイアリー

はてなダイアリーから移行中…

__declspec(align(16))

今作っている作品はシューティングなので、スコア等を表示をしなくてはなりません。そこで、こんなコードを書いてました。

<イメージコード>
typedef __declspec(align(16)) _D3DXMATRIXA16 D3DXMATRIXA;

class C8NumChar // 数字一文字
{
  D3DXMATRIXA m_sMatrix;
    : // 他色々
};

class C8Score
{
  std::vector<C8NumChar> m_stlNumList;
    : // 他色々
public
  C8Score(CUINT nKeta) : m_stlNumList(nKeta){}
};
</イメージコード>
テクスチャにある数字1文字を表示するクラスをつくり、vectorで桁数分確保するって感じです。…が、これ、C8NumCharで aling指定してる型があるためか、コンパイラに怒られます。(配列を確保する時、動的に確保するのでアライメントが保証出来ないので怒られるのかも?)
仕方ないので、こう書きなおしました。

<イメージコード>
typedef __declspec(align(16)) _D3DXMATRIXA16 D3DXMATRIXA;

class C8NumChar // 数字一文字
{
  D3DXMATRIXA m_sMatrix;
    : // 他色々
};

template<UINT N> // クラステンプレート化
class C8Score
{
  boost::array<C8NumChar, N> m_stlNumList;
    : // 他色々
public
  C8Score(){}
};
</イメージコード>

こうすれば、コンパイル時に配列の大きさが分るのでさくっとコンパイルが通ります。

しかし、使いつづけていくうちに、クラステンプレートという点がネックで、使いづらくなってきました…。どうしたものか。
私的には Matrix は 16byteアライメントにいて欲しいので、__declspec指定ははずしたくないし…。だからといって、vector じゃ無理だし new C8NumChar[N] でも、保証は無いような気がするし〜。う〜ん……。

……しかし、よく考えてみれば、コレでよかったことに気づく。

<イメージコード>
typedef __declspec(align(16)) _D3DXMATRIXA16 D3DXMATRIXA;

class C8NumChar // 数字一文字
{
  D3DXMATRIXA* m_psMatrix;
    : // 他色々
public:
  // Matrixを動的確保
  C8NumChar() : psMatrix(new D3DXMATRIXA){}
};

class C8Score
{
  std::vector<C8NumChar> m_stlNumList;
    : // 他色々
public
  C8Score(CUINT nKeta) : m_stlNumList(nKeta){}
};
</イメージコード>

_D3DXMATRIXA16 には、専用の new が定義されていることをすっかり忘れてました。 orz
まぁ new して確保している点がちょっと気になりますが、auto_ptr に囲んでしまえば問題なくなりますし、気分的な問題だけが残るかなー って感じです。

……実はこのコード、私の知らないワナとか潜んでたりして…。大丈夫だよなぁ。