2011年12月12日月曜日

マクロで #pragma

#pragma warning(push)
#pragma warning(disable:4996)
#pragma warning(pop)

警告抑制のプラグマです。
Visual Studio では、これはこのようにも書けます。
__pragma( warning(push) )
__pramga( warning(diable:4996) )
__pragma( warning(pop) )

これまでなんとか #pragma を簡潔に書けないものかと思っていたのですが、
#define PRAGMA(x) #pragma x
とか、やってみたり(もちろんコンパイルエラー)
#define MESSAGE(x) message (x)
#pragma MESSAGE("TODO")
としてみたり(なんかかっこ悪い)。

しかし、__pragma を使えばマクロに収めることが可能になるのです!
#define WARN_DISABLE_CRT_SECURE_BEGIN() \
__pragma(warning(push))               \
__pragma(warning(disable:4996))

#define WARN_DISABLE_CRT_SECURE_END()   \
__pragma(warning(pop))

void func(char* a, const char* b)
{
  WARN_DISABLE_CRT_SECURE_BEGIN()
  strcpy(a, b);
  WARN_DISABLE_CRT_SECURE_END()
}
__pragma は、Visual Studio の独自機能です。(たぶん)
では、他のコンパイラではどうかというと、
_Pragma が使えることが多いようです。

なので、以下のようなマクロを作っておくと便利かもしれません。
#ifdef _MSC_VER
#  define MY_PRAGMA(x)  __pragma(x)
#else
#  define MY_PRAGMA(x)  _Pragma(x)
#endif
これを使うことで環境依存を吸収しやすくなりました。
めでたしめでたし。

編集後記
この記事を書いてから、公開を迷っていたら C++11 Advent Calendar で _Pragma の記事が先に上がってました。
http://d.hatena.ne.jp/Flast/20111208/1323356748
そちらの記事を読んで、_Pragma が C++11 の新機能?あれ?
と、無知な私は思ったのですが、
_Pragma は C99 の規格で、 C++ では C++11 から採用されたんですね。

ところで、Visual Studio 2010 ではどうなっているのだろうと試しました。
_Pragma は使えず。
__pragma は使えました。
(Microsoft Visual Studio 2010 Version 10.0.40219.1 SP1Rel)
Visual Studio の C++11 対応はどうなるんでしょうね。

0 件のコメント:

コメントを投稿