デバッグをスムーズに進めるにはどうすれば良いか。一つは、できるだけ早い段階でバグ(ミス)に気付くことです。assertやその派生マクロは、バグを早期発見する上で非常に有効な手段ですが、条件チェックは実行時でないと行われません。実行時ではなく、コンパイル時に静的にバグを発見できれば非常に便利です。
このようなコンパイル時の静的チェックのひとつがstatic_assertです。例えば、次のようにして使用します。
では、このようなstatic_assertはどのようにして定義するのでしょうか。C++では、boost等でも用意されているtemplateを用いた方法がありますが、ここではCでも実現可能な方法を紹介します。
【関連書籍】
・Modern C++ Design―ジェネリック・プログラミングおよびデザイン・パターンを利用するための究極のテンプレート活用術
このようなコンパイル時の静的チェックのひとつがstatic_assertです。例えば、次のようにして使用します。
int send_msg(void* msg, size_t size);
int func()
{
my_type_t my_data;
....
STATIC_ASSERT(sizeof(my_type) <= sizeof(msg_t));
send_msg(&my_data, sizeof(my_data));
}
通常のassertであれば、実行時上記コードを通った段階でabort()等で気付かせてくれますが、static_assertの場合は、コンパイル時にエラーになります。では、このようなstatic_assertはどのようにして定義するのでしょうか。C++では、boost等でも用意されているtemplateを用いた方法がありますが、ここではCでも実現可能な方法を紹介します。
#define STATIC_ASSERT(expr) { char dummy[(expr) ? 1 : 0]; }
分かるでしょうか?通常長さ0の配列はコンパイルエラーになるため、exprがコンパイル時に成立していないと、コンパイルエラーになるのです。この方法の欠点は、エラーメッセージが「長さ0の配列は定義できません」等の意味不明なメッセージになる点です。C++でtemplateを用いた凝った方法を使うと、もう少し分かりやすいメッセージ表示にすることも可能です(関連書籍が参考になります)。【関連書籍】
・Modern C++ Design―ジェネリック・プログラミングおよびデザイン・パターンを利用するための究極のテンプレート活用術
| ホーム |










