ラベル c の投稿を表示しています。 すべての投稿を表示
ラベル c の投稿を表示しています。 すべての投稿を表示

2016年2月2日火曜日

[C/C++][Clang] include 解析ツールを作った

無駄な include を消したいなーと思って、そのためにまずは解析できるようにならないと、と Clang を使ってやってみました。

ビルド環境構築
clang ソースのセットアップ
LLVM.org から LLVM と clang のソースをダウンロードします。
それぞれ展開をし、LLVM は任意のファルダに保存してください。

ここでは、 D:\usr\local\LLVM に置いたこととします。
clang は展開したフォルダを "clang" にリネームして、 D:\usr\local\LLVM\tools\clang に置きます。

clang のビルド
今回は Visual Studio 2015 向けにビルドします。
その前に CMake が必要になるので、インストールしておいて下さい。

コマンドプロンプトを開き、LLVM ソースフォルダに移動して、以下のコマンドを実行します。
LLVM> set path=%ProgramFiles(x86)%\CMake\bin
LLVM>mkdir build
LLVM>cd build
LLVM\build>cmake -G "Visual Studio 14" -D CMAKE_INSTALL_PREFIX=D:\LLVM ..

最初に path を書き換えているのは、cygwin のパスが通ってると CMake に失敗するためです。
CMAKE_INSTALL_PREFIX にはインストールフォルダを指定します。今回は D:\LLVM としています。
CMake が成功すると、LLVM.sln が出来上がってるのでビルドします。

ビルドができたら、INSTALL プロジェクトを選択してビルドします。
CMAKE_INSTALL_PREFIX に指定したところにインストールがされますので、これで完了です。

事始め
まずは、なにかサンプル的なものをビルド・実行できるようにするとイイと思います。
今回私は、以下のページを参考にしました。

include の解析
今回は #include の依存関係を知ることが目的です。
プリプロセスの追跡には PPCallbacksTracker を使うことになります。

そして include の依存関係から dot ファイルを作成するスゴク参考になりそうなものが clang/lib/Frontend/DependencyGraph.cpp にあります。
これを参考に書いたのがこちら。
https://github.com/srz-zumix/cincluder

システムファイルを除外したり、複数ファイルから include されているファイルに色付けするようにしています。
iutest を解析した結果がこちら。


コマンドラインオプション
cincluder を書いていて独自のコマンドラインオプションに対応したいなと思って調べたのでメモ。

static cl::OptionCategory CincluderCategory("cincluder");
static cl::opt< ::std::string > DotFile("dot", cl::init("cincluder.dot"), cl::desc("output dot file"), cl::cat(CincluderCategory));

cl::opt でオプションを定義します。
最初の文字列がオプション名で、あとは init で初期値、 desc で説明、 cat でカテゴリ情報を付与しています。
これらの設定には、cl::Positional とか、 cl::Required とかもあるみたいです。
他にどんな設定があるかは、 LLVM/include/llvm/Support/CommandLine.h を参照してください。

最後に
LibTooling 難しそうと思ってましたが使ってみたらそうでもなく、やりたいことがこんなにも簡単にできてしまうのかー、と驚きました。
「できる」というのが分かってしまえば気楽なもんで、お仕事とかでも気軽にツール作りができそうです。

2015年4月20日月曜日

iutest_c v1.5.1 をリリースしました

iutest_c v1.5.1 をリリースしました。

bugfix バージョンです。
coveralls 連携がうまく動くようになったので、カバレッジ上げつつテスト書いてたらいっぱいバグが見つかりました(ノ∀`)
どうせならパワーアップして v1.6.0 を出そうかと思ったんですが、優先度的に"なし"になりました。

新しいことやりたいですしね( ^ω^ )

2014年7月31日木曜日

iutest_c v1.5.0 をリリースしました

iutest_c v1.5.0 をリリースしました。

変更点は以下のとおりです。

  • 修正
    • _Generic 対応
    • バグ修正

今回は _Generic 対応が目玉ですが、
テストの充実化をしたことで、バグを大幅に減らせました。

2014年6月25日水曜日

[C11] _Generic を使ってみた

gcc 4.9 で _Generic が使えるようになったので、使ってみました。
(clang では結構前から使えたみたいですね)

_Generic とは?
_Generic(制御式, 型名1: 式1, 型名2: 式2…)
_Generic は与えられた型によって評価される式を決定する式です。
これはコンパイル時に決定されます。

例えば、以下のように使用できます。
#define abs(x) _Generic((x), long: labs, double: fabs, default: abs)(x)

_Generic 自体については他のサイトも参考にしてください。

やろうとしてできなかったこと

#define printf_dec_format(x) _Generic((x), \
    char: "%c", \
    signed char: "%hhd", \
    unsigned char: "%hhu", \
    signed short: "%hd", \
    unsigned short: "%hu", \
    signed int: "%d", \
    unsigned int: "%u", \
    long int: "%ld", \
    unsigned long int: "%lu", \
    long long int: "%lld", \
    unsigned long long int: "%llu", \
    float: "%f", \
    double: "%f", \
    long double: "%Lf", \
    char *: "%s", \
    void *: "%p")
Rob's Programming Blog: C11 - Generic Selections

#define Message(a, b) \
    printf("a = " printf_dec_format(a) "\nb = " \
         printf_dec_format(b) "\n", a, b)

文字列リテラルは以下のように途切れていても1つの文字列リテラルとして扱われるので、それを期待したのですがダメでした。
printf( "aaaa" "bbbb" "\n");

メンドクサイですが、このように書く必要があるようです。
#define PRINTF_FORMAT_PARAM(prefix, x, postfix) _Generic((x) \
    , char : prefix "%c" postfix                \
    , signed char: prefix "%hhd" postfix        \
    , unsigned char: prefix "%hhu" postfix      \
    , signed short: prefix "%hd" postfix        \
    , unsigned short: prefix "%hu" postfix      \
    , signed int: prefix "%d" postfix           \
    , unsigned int: prefix "%u" postfix         \
    , signed long: prefix "%ld" postfix         \
    , unsigned long: prefix "%lu" postfix       \
    , char* : prefix "%s" postfix               \
    , void* : prefix "%p" postfix               \
    , default: prefix "%p" postfix              \
    )

#define PRINTF_FORMAT_PARAM2(str0, x, str1, y, str2) _Generic((x)    \
    , char : PRINTF_FORMAT_PARAM(y, str0 "%c" str1, str2)            \
    , signed char: PRINTF_FORMAT_PARAM(y, str0  "%hhd" str1, str2)   \
    , unsigned char: PRINTF_FORMAT_PARAM(y, str0  "%hhu" str1, str2) \
    , signed short: PRINTF_FORMAT_PARAM(y, str0  "%hd" str1, str2)   \
    , unsigned short: PRINTF_FORMAT_PARAM(y, str0  "%hu" str1, str2) \
    , signed int: PRINTF_FORMAT_PARAM(y, str0  "%d" str1, str2)      \
    , unsigned int: PRINTF_FORMAT_PARAM(y, str0  "%u" str1, str2)    \
    , signed long: PRINTF_FORMAT_PARAM(y, str0  "%ld" str1, str2)    \
    , unsigned long: PRINTF_FORMAT_PARAM(y, str0  "%lu" str1, str2)  \
    , char* : PRINTF_FORMAT_PARAM(y, str0  "%s" str1, str2)          \
    , void* : PRINTF_FORMAT_PARAM(y, str0  "%p" str1, str2)          \
    , default: PRINTF_FORMAT_PARAM(y, str0  "%p" str1, str2)         \
    )

#define Message(a, b) \
    printf(PRINTF_FORMAT_PARAM2("a = ", a , "\nb = ", b, "\n"), a, b)
もっと効率的な書き方があればコメント下さい。

指定した名前が型であるかどうか調べるマクロ


というわけで、C11 でも書いてみた。

#include <stdio.h>

#define IS_TYPE_NAME(name) _Generic((void (*)(int (name)))0, void (*)(int):0, default: 1)

typedef float f;
int main()
{
    printf("%d\n", IS_TYPE_NAME(int));
    printf("%d\n", IS_TYPE_NAME(f));
    printf("%d\n", IS_TYPE_NAME(main));
    printf("%d\n", IS_TYPE_NAME(aaa));
    return 0;
}

1
1
0
0

なにかに使えそうな気がする。

iutest_c での利用
はじめに iutest_c を紹介しておきます。
iutest_c は「C言語のテスティングフレームワーク」です。C++テスティングフレームワークの iutest もありますが、こちらはC言語で書かれています。C++ のと比べると非常に貧弱なフレームワークですが、軽量であることは間違いありません。(小さなデバイスなどに載せることを想定していますが、あまり検証もできていませんし、そこに載せることを考えると軽量とは言い難いかも)

printer の改善
貧弱な点の一つとして、printer がビミョーでした。
アサーションに失敗した場合、期待値と実値を出力します。この時の出力が値ではなくメモリダンプを出力します。
IUTEST(Test, Sample)
{
    int zero=0;
    IUTEST_EXPECT_NE(zero, zero);
}
sample.c(16):error: Expected of :
zero != zero
Actual: 0x00000000 vs 0x00000000

ビミョー過ぎて説明するのもアレなんですが、一番ダメなところとして lvalue しか扱えないところです。
IUTEST_EXPECT_NE(0, 0); と書けません。

そこで _Generic!!

前述した printf_dec_format のように、型ごとに出力をしてあげることで lvalue 制限を取り払い、わかりやすい出力を実現しました。

IUTEST(Test, Sample)
{
    IUTEST_EXPECT_NE(0, 0);
    float fa = 2.0f/2;
    IUTEST_EXPECT_FLOAT_EQ(1.1f, fa);
}
sample.c:15:error: Expected of :
zero != zero
Actual: 0 vs 0
sample.c:17:error: Value of : fa
Actual: 1.000000
Expected: 1.1f
Which is: 1.100000



ネタ切れ
このブログを書きつつ、_Generic の利用方法を考えていたのですが、ネタ切れです。

_Generic 使ってもっと何かできるんじゃないかと思っていたのですが、なかなかうまくいかず。。。
例えば、decltype とか書けるんじゃないか?と思ったんですが、式しか扱えないのでダメでした。
関数オーバーロードの代用として使えるので、それで…と思ったんですが使いドコロがなかった。
IS_TYPE_NAME 使って何かできそうな気はするんですがねぇ…

まとめ
_Generic 便利だと思いますが、どの位需要があるんでしょうね?
C11 使うことができるんなら、C++ 使えばいいんじゃない?と思ってしまいます。

とはいえ、_Generic は便利です。iutest_c でも今後も使っていこうと思います。

2014年5月21日水曜日

iutest_c v1.4.0 をリリースしました

iutest_c v1.4.0 をリリースしました。
約9ヶ月ぶりの更新です。
iutest (C++ testing framework)の方にかかりきりで更新できていませんでしたが、C11 の _Generic が gcc 4.9 で使えるようになったらしいので、対応作業に移る前にリリースすることにしました。

変更点は以下のとおりです。

  • 追加
    • IUTEST_SKIP 追加
    • iuBoolean パラメータジェネレータを追加
    • セクション指定に対応
    • 機能削減用コンフィグマクロを追加
  • 修正
    • コードサイズ削減

v1.5.0 では _Generic に対応したいなぁーと思っていますが・・・
果たして、C言語のテスティングフレームワークって需要あるんですかね?

2013年8月20日火曜日

iutest_c v1.3.0 をリリースしました

iutest_c 1.3.0 をリリースしました。

今回の変更点は以下のとおりです。

  • iuCombine を追加
  • IUTEST_*_FATAL_FAILURE, IUTEST_*_NON_FATAL_FAILURE を追加
  • IUTEST_*_NO_FATAL_FAILURE, IUTEST_*_NO_FAILURE を追加
  • 明示的な成功と失敗を追加
  • 値のパラメータテストの明示的登録に対応

iuCombine を追加
今回の変更での目玉です。
v1.2.0 で値のパラメータテストに対応しましたが、Values と Range しか使えませんでした。
今回 v1.3.0 で iuCombine を追加し、パラメータの組み合わせテストを書けるようになりました。

iuCombine の使い方は iutest や gtest のそれとは少し違うので簡単にですが説明しておきます。

typedef IUTEST_P_TYPE((int, char, unsigned int)) TestCombineParamType;
IUTEST_INSTANTIATE_TEST_CASE_P((int, char, unsigned int), A
                               , TestCombine, iuCombine
                               , (iuRange, ( 0, 2)), (iuStepRange, (100, 110, 2)), (iuValues, (0, 4, 2)) );

IUTEST_P(TestCombineParamType, TestCombine, Test)
{
    const int x0 = param.value0;
    const char x1 = param.value1;
    const unsigned int x2 = param.value2;
    iuConsole_Output("%d %d %d\n", x0, x1, x2);
}
まずはじめに、IUTEST_P_TYPE マクロを使ってパラメータの型を定義します。
第一引数に、型のリストを()で括った形(以下、タプルと呼びます)で渡します。
これは、IUTEST_P のテスト関数に渡されるパラメータ変数の型として使います。

次にテスト関数を作成します。
こちらは通常の値のパラメータテストと同じように IUTEST_P で定義します。
第一引数に先ほど定義した型を指定、
第二引数がテストケース名、第三引数がテスト名です。

次に組み合わせを作成します。
IUTEST_INSTANTIATE_TEST_CASE_P を使うのは通常の値のパラメータテストと同じです。
第一引数には、IUTEST_P_TYPE で渡したものと同じ型のリストをタプルで渡します。
(※ 2回も書く必要があって面倒ですが…)
第二引数には、このパラメータのインスタンスのプレフィックス名を渡します。
これは重複しない名前ならなんでも構いません。
第三引数にはテストケース名、第四引数に iuCombine を指定します。

ここからが iuCombine の特殊な書き方になります。
第五引数以降には、iuCombine のパラメータを渡します。
個々のフォーマットは、
( ジェネレータ名, (ジェネレータのパラメータ) )
のようになります。
ジェネレータとジェネレータのパラメータを () で一纏めにして渡しています。
また、ジェネレータのパラメータもタプル形式でまとめています。
ジェネレータには iuValues や iuRange などが使用できます。

最後にパラメータの取り出し方ですが、
IUTEST_P のテスト関数に param 変数名でパラメータを保持した構造体が渡されます。
各パラメータは param.value0,param.value1... のように格納されているので、
そこから参照することができます。

実行するとこんな感じになります。


IUTEST_*_FATAL_FAILURE, IUTEST_*_NON_FATAL_FAILURE を追加
gtest における spi にあたる機能に対応しました。
若干ログメッセージがあれですが、とりあえずテストが失敗することを検証できるようになりました。

IUTEST_*_NO_FATAL_FAILURE, IUTEST_*_NO_FAILURE を追加
今度は逆に、テストが失敗していないことを検証するマクロです。
サブルーチンで発生したテスト失敗を検知するために使ったりします。

明示的な成功と失敗を追加
表題通り、明示的な成功と失敗に対応しました。

値のパラメータテストの明示的登録に対応
v1.2.0 のバグ修正です。
テスト関数の自動登録が使えない環境では、テストを明示的に登録する必要がありますが、
値のパラメータテストの関数が登録できないバグを修正しています。

次のバージョン
次のバージョンでは組込み環境で使ってみたりして、コードサイズとか細かいところをケアしていこうと思います。

2013年5月6日月曜日

iutest_c v1.2.0 をリリースしました

iutest_c v1.2.0 をリリースしました。
今回は「値のパラメータ化テスト」が主な変更点になります。


iutest の記述と大分異なりますが、直感的な記述ができるようになったと思います。
IUTEST_INSTANTIATE_TEST_CASE_P(int, A, TestP, iuRange, 0, 2 );

IUTEST_P(int, TestP, Test)
{
    const int x = param; // パラメータは param 引数として渡されます
    const int kMax = 10;
    IUTEST_ASSERT_LT(x, kMax);
}

次のバージョンでは、Combine と組み込み向け対応を強化したいと思います。
それでは。

2013年3月1日金曜日

iutest_c v1.1.0 をリリースしました

iutest_c v1.1.0 をリリースしました。

ライブラリビルド対応とテストフィクスチャにユーザーデータを渡せるようになってます。
次は値のパラメータ化テストへの対応を予定していますが・・・できるのだろうか・・・

2013年1月7日月曜日

[Visual Studio] プリプロセス結果を IDE で見る方法

マクロを使っていると、ちょっとした間違いでよくわからないエラーが出たりしますが、
どこが間違っているか探すのがちょっと大変だったりしますよね。
そういう時にプリプロセッサだけ通したテキストを出力して、マクロがどのように展開されているのか見て探すこともあると思います。

Visual Studio の場合、 cl.exe /P hoge.cpp でプリプロセス済みファイルが出力されますが、
これを IDE から1操作でやろうと思います。

外部ツールを使う
[ツール]メニューにある[外部ツール]を使用します。

[外部ツール]をクリックすると、ダイアログが開きます。
[追加(A)]ボタンを押し、画像のように入力します。
[タイトル]はお好みでつけてください。


[コマンド]のところを入力するまえに、
下記の内容を適当な場所にバッチファイル(.bat)として保存します。
そして、保存したファイルのパスを[コマンド]に入力してください。
@echo off
call "%VS110COMNTOOLS%\vsvars32.bat"

rem プリプロセス
rem 結果は .i 拡張子で出力される
cl.exe /P /C "%~1"

rem 出力ファイルを関連付けられたアプリケーションで開く
rem この辺はお好みで編集してください。
call "%~dp1\%~n1.i"

rem 使い終わったら消す
del /F "%~dp1\%~n1.i"

以上で設定は終わりです。

このバッチファイルが今回の肝になります。
バッチの説明の前に、試しに実行してみましょう。
使用方法
  1. ソースウィンドウでプリプロセス結果を見たいファイルを選択します。
  2. [ツール]-[Preprocess] をクリック(Preprocess は設定で付けたタイトル名)
  3. 選択したソースファイルの .i 拡張子ファイルが開きます。(※)
※ .i 拡張子に関連付けられたアプリケーションで開きます。お使いの Visual Studio に関連付けると IDE で開きます。



解説
仕組みは単純で、cl.exe が出力した .i ファイルを開いているだけです。
そのため .i 拡張子に関連づいたアプリケーションで開きます。

.i 拡張子に Visual Studio を関連付けても良いですし、お気に入りのエディタに関連付けても良いです。
バッチファイルでやることも自由なので、自分好みにバッチファイルを編集してください。

最後に
あまり良い仕組みではないですが、こんなこともできるんだー程度に思っていだければ。




2012年11月30日金曜日

iutest_c v1.0.0 をリリースしました

iutest_c は C言語で書かれたテスティングフレームワークです。

iutest と同様にヘッダオンリーで使用することができます。
C++ のテスティングフレームと比較して機能的には大分劣ります。
そもそも C言語のテスティングフレームが必要とされているのか疑問ではあります。
別にテストは C++ で書いてもいいわけですから。
(組み込みだとそうでもないのかなぁ)

ともあれ、 iutest_c の特徴的な機能を紹介したいと思います。

書き方
iutest_c は iutest から派生したプログラムです。
テストの書き方はほとんど同じです。
また、iutest は Google Test を踏襲してますので、 Google Test を使っている人には分かりやすいと思います。

もっとも簡単なテストを紹介します。

IUTEST(CaseName, TestName)
{
    int x = 0;
    IUTEST_ASSERT_EQ(0, x);
}

テストを自動検出して実行
iutest_c でもテストを自動で検出して実行します。
テストの登録用変数を定義したり、登録関数を呼んだり、面倒な手続きが不要です。
(※非対応コンパイラあり。その場合は、IUTEST_REIGSTER_TEST マクロで明示的な登録が必要です。)

テストフィクスチャ
iutest_c でもテストフィクスチャが使えます。

void TestF_SetUp(void)
{
  /* ここに SetUp コード */
}
static const iuTestFixture TestF = { NULL /* SetUpTestCase */
                                  , NULL /* TearDownTestCase */
                                  , TestF_SetUp /* SetUp */
                                  , NULL /* TearDwon */
                                  };
IUTEST_F(TestF, Hoge)
{
   IUTEST_ASSERT_TRUE(TRUE);
}

iuTestFixture 構造体に TestCaseSetUp/TearDown,SetUp/TearDown 関数を設定します。
テストケース名にこの変数名を指定して下さい。

簡易的なパラメタライズテスト
関数の引数に値を渡すテストを簡単に記述できます。
void TestFunction(int x, int y)
{
    IUTEST_ASSERT_EQ(x, y);
}
IUTEST_PMZ(ParamMethodTest, EQ, TestFunction, 0, 0);
IUTEST_PMZ(ParamMethodTest, EQ, TestFunction, 1, 1);
IUTEST_PMZ(ParamMethodTest, EQ, TestFunction, 2, 2);


今後の予定
値のパラメータ化テストに対応できるような気がしないでもないので、
v1.1 はそれを目標に開発を続けたいと思います。

2012年4月6日金曜日

C で main の前に関数コール

C言語のテストフレームワークを書いていて知ったこと。

C言語版のテストフレームワークでも、Google Test のようにテストの登録をいちいちしなくていいインターフェイスを目指していました。

それを実現するためには、どうしても main 関数が呼ばれる前に関数を呼ぶ必要がありました。
C++ なら、
int dummy = func();
int main()
{
    return 0;
}
とか、コンストラクタとか使う方法があったのですが、
C だと、上の方法が使えず。(いけると思っていたのでガッカリ)
もちろんコンストラクタなどないので、どうしたもんかという状態でした。

__attribute__((constructor))
Google 先生に聞いてみると __attribute__((constructor)) ってのがヒット。

これだ!えいや!できたー!!

あ、でもコレ GCC でないとダメじゃん。

あきらめるのはまだ早い
gcc には __attribute__((constructor)) というものがあるが、
Visual Studio ではどうしたらいいの?という事で、Google で検索してみると以下の記事がヒットしました。
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc

まんま答えがありました。 CRT$XCU を使うようです。

CRT のグローバル初期化にぶち込むってことですかね。
MSDNにも説明がありました。

こちらも問題なく動作しました。
とりあえず、Visual Studio と GCC で使えれば個人的に満足なので、他の環境は考えないことにする。

C言語テストフレームワークとしての iutest
branche で作業してますので、良かったら見てください。

今のところ、以下のような感じでテストが書けるようになりました。
#include "iutest_c.h"

IUTEST_C_WORKSPACE(); // ワークの構築用に必要...

int main(int argc, char* argv[])
{
    iuInitIrisUnitTest(&argc, argv);
    return IUTEST_RUN_ALL_TESTS();
}

IUTEST(AssertionTest, Simple)
{
    IUTEST_ASSERT_EQ(0, 0);
    IUTEST_ASSERT_NE(0, 1);
    IUTEST_ASSERT_LE(1, 1);
    IUTEST_ASSERT_LT(0, 1);
    IUTEST_ASSERT_GE(1, 1);
    IUTEST_ASSERT_GT(1, 0);
}

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 対応はどうなるんでしょうね。