スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

コンパイル時の静的チェック(STATIC_ASSERT)

早起きは3億の徳

デバッグをスムーズに進めるにはどうすれば良いか。一つは、できるだけ早い段階でバグ(ミス)に気付くことです。assertやその派生マクロは、バグを早期発見する上で非常に有効な手段ですが、条件チェックは実行時でないと行われません。実行時ではなく、コンパイル時に静的にバグを発見できれば非常に便利です。

このようなコンパイル時の静的チェックのひとつが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 static_assertion_failed[(expr) ? 1 : 0]; }
分かるでしょうか?
通常長さ0の配列はコンパイルエラーになるため、exprがコンパイル時に成立していないと、コンパイルエラーになるのです。この方法の欠点は、エラーメッセージが「長さ0の配列は定義できません」等の意味不明なメッセージになる点です。少しでもわかりやすくするために、上の例では、変数名をstatic_assertion_failedとしています。
その他、C++でtemplateを用いた凝った方法を使うと、もう少し分かりやすいメッセージ表示にすることも可能です(関連書籍が参考になります)。


4894714353 【関連書籍】
Modern C++ Design―ジェネリック・プログラミングおよびデザイン・パターンを利用するための究極のテンプレート活用術

コメント

No title

>この方法の欠点は、エラーメッセージが「長さ0の配列は定義できません」等の意味不明なメッセージになる点

変数名 dummy を、STATIC_ASSERT 等としておくと、より分かり易いと思いました。
エラーメッセージ表示は、同時に当該コードされる事が殆どだろう為です。
非公開コメント

本のおすすめ

4873115655

4274065979

4822236862

4274068579

4822255131

B00SIM19YS


プロフィール

  • Author:proger
  • 組み込み関係で仕事してます

ブログ内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。