_SECURE_SCLによる差

_SECURE_SCLは、チェック付きイテレータ用の定義シンボルです。
STLvectorやlistをインクルードする際に

#define _SECURE_SCL 1 // 有効にする
//#define _SECURE_SCL 0 // 無効にする
#include <vector>

という感じで使います。
チェック付きイテレータとは何か、というのは
以下のMSDNを見て貰えるとよいと思います。
http://msdn.microsoft.com/ja-jp/library/aa985965.aspx


こちらを使っていて、起き得る問題についてのお話を今日は少し。

#include <cstdio>
#include <vector>

int main(int argc, char* argv[]) {
  typedef std::vector<int> IDs;
  printf("_SECURE_SCL = %d\n", _SECURE_SCL);
  printf("sizeof(IDs) = %d\n", sizeof(IDs));
  return 0;
}

こちらの、ただのstd::vectorのサイズを返すプログラムですが
_SECURE_SCLが、有効か無効かで異なる結果になります。


以下が、VisualStudio.net2010(VC10)での結果です。

_SECURE_SCL = 1
sizeof(IDs) = 20
_SECURE_SCL = 0
sizeof(IDs) = 16

と、_SECURE_SCLの設定で異なったサイズを返すのです。


これ単体では、確かにそう問題にはならないのですが、
例えば、スタティックライブラリと、それをリンクしている
メインプログラムで_SECURE_SCLの設定が異なった場合は
クラスサイズに齟齬が出る影響で、アクセス違反などを起こす場合があります。


また、これの厄介なところは、クラスサイズが異なるのは
「Release」のみです(正確には、NDEBUG定義の有無)。
_SECURE_SCL以外にも、定義の有無でサイズが変わるものは
同様の危険があるので、気をつける必要があると思います。