2012年7月21日土曜日

_ASSERTで警告ダイアログを出す

元々C言語にassert()というマクロがありますがVC++では

#include <crtdbg.h>
をインクルードして
_ASSERT(0)
とか
_ASSERTE(0)
でプログラムを中断させる事が出来ます。

C言語のassertは<assert.h>というヘッダをインクルードすれば利用できますがVC++版の方が警告発生時のコード追跡が便利だったりするかも知れません。

アサートの仕組みは
カッコの中が0(つまり条件式がfalse)ならダイアログボックスで警告が出ます。それ以外ならそのまま通過して何も起きません。
 Debugビルドで開発中に、「まぁ、こういう条件にはならないだろうけど、もしなった場合はすぐに知りたい」とか、 「開発中に起こり得る仕様外の出来事なので、これで知らせよう」という状況で使うのが一般的かと思います。
Releaseビルドした場合はアサートの文自体がカッコの中も含めて丸々消えてしまうのでこのマクロを使いまくってもパフォーマンスの低下は起きません。

使用例

int*p = 0;

int GetNum()
{
 //pが初期化前(0のまま)だったらアサート
 _ASSERT(p);

//無事通過したので内容を返す
 return *p;
}

・・・つまり
クラス内のメンバが初期化前に使われそうになった時などに有効でしょう。
if文で分岐してエラーを返したい場合もあるかも知れませんが、想定外のパターンをすぐに発覚させていきたいという場合にはアサートしましょう。

あとは配列の範囲チェックとかに使う?
void Set(int id, int num)
{
int p[10];
_ASSERTE(id>=0 && id <10);
p[id] = num;
 }

_ASSERTと_ASSERTEの違いは警告時に()の中の条件式が表示されるかどうかです。条件式が表示されると警告が出た時に問題の箇所が分かり安いという利点があるのですが、いずれにせよVC++でビルド実行中なら「再試行」ボタンを押せば問題の箇所に飛べるのでさほど利点がないかも知れません。

_ASSERT(0 && "Σ (゚Д゚;)カクカクシカジカでテラヤバス!");
と書くと

このようになります。
&&の左側がfalseの時点でfalse確定なので右側の式は評価されないので普通にアサートされて、()の内容がそのまま表示されるという仕組みです。条件式だけを書くよりも原因の特定を容易にします。

しかし、自分でデバッグする場合はコード中の_ASSERTのそばになぜアサートを設けたかをコメントしておけば済むという噂もあります。

文字列をやたら使うとメモリを食うから、それが気になる場合はこちらではなく_ASSERTを使うようにとMSDNのCRT アサーションというページには書いてありました。

0 件のコメント: