バグ予防として「const」を説明しましたが、もう1つ新しいものを紹介します。
それは「アサーション(assertion)」という考え方です。
「assert.h」をインクルードする事で、assertというマクロが使えるようになります。
assertの文法は↓のようになります。
assert(条件); |
この条件が成り立たなかった時に、プログラムは実行を停止します。
1つサンプルを作りましょう。
<sample program 185-01>
#include <stdio.h> #include <assert.h> void ShowValue(const int value); int main(void) { int data; data = 15; ShowValue(data); return 0; } void ShowValue(const int value) { assert(value >= 0); printf("value = %d\n", value); } |
<実行結果>
value = 15 続行するには何かキーを押してください・・・
関数ShowValueは「const int型」の引数を1つ受け取ります。
この引数は0以上であり、負の値を受け取る事はありません。
ありませんが、もし負の値が渡されたら「渡した側のプログラムが間違っている」可能性があります。
それを発見するための仕組みとして使えます。
main関数のdataに負の値を入れて実行してみてください。
<sample program 185-02>
#include <stdio.h> #include <assert.h> void ShowValue(const int value); int main(void) { int data; data = -5; ShowValue(data); return 0; } void ShowValue(const int value) { assert(value >= 0); printf("value = %d\n", value); } |
<実行結果>
エラーで止まってしまいました。
コンソール画面を見ると、
こうなっています。
assert(value >= 0) |
と書いてある箇所で止まりました。
場所は、
main.cppファイルの19行目
だと書いてあります。
もう1つサンプルを書いてみます。
<sample program 185-03>
#include <stdio.h>
#include <assert.h>
void Select(const int number);
int main(void)
{
Select(1);
Select(5);
return 0;
}
void Select(const int number)
{
switch (number) {
case 1:
printf("Select1\n");
break;
case 2:
printf("Select2\n");
break;
default:
assert(0);
}
}
|
この関数には引数として1か2だけが渡される事になっています。
しかし、何が渡されるか分かりませんのでswitch文のdefault部分にassertを書いておきます。
assert(0); |
と書いておけば、条件的には常に成り立ちません。
実行するとエラーになりますが、試してください。
実はこのassertの特徴はもう1つあるのです。
「Debug」モードでのみ動作し、「Release」モードの際にはコンパイルされません。
開発時のバグ予防が目的ですから、アプリケーションをリリースする時には不要なコードとなります。
リリース時にプログラマがassertを消さなくても良いようになっているのです。
同じような動作が可能な仕組みとして「_DEBUG」があります。
サンプルを作ってから説明しましょう。
<sample program 185-04>
#include <stdio.h> int main(void) { printf("Start!\n"); #ifdef _DEBUG printf("Process\n"); #endif printf("End\n"); return 0; } |
<実行結果>
Start! Process End 続行するには何かキーを押してください・・・
「ヒット&ブロー」で説明したプログラムを無効にする方法に似ています。
今回の、
#ifdef _DEBUG printf("Process\n"); #endif |
の部分は無効になっていません。
#ifdef _DEBUG |
この部分は「もし_DEBUGが定義されていたら」という意味になります。
自分で定義した覚えはありませんが、「Debug」モードの時は定義されています。
そして、「Release」モードの時は定義されなくなるのです。
「Release」モードに変更して実行してみましょう。
※「Release」モードへの切り替えは、こちらで確認してください。
<実行結果>
Start! End 続行するには何かキーを押してください・・・
実行結果から「Process」の文字が消えています。
assertと同じように、開発中だけ動作させたいコードを書いておけば、リリース時には自動的にコンパイルから外されるのです。
便利な機能ですから、色々なところで使ってみてください。