★バグ予防&デバッグコード★


バグ予防として「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


同じような動作が可能な仕組みとして「_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と同じように、開発中だけ動作させたいコードを書いておけば、リリース時には自動的にコンパイルから外されるのです。

便利な機能ですから、色々なところで使ってみてください。


次へ

戻る

目次へ