最終更新日時:
が更新

履歴 編集

macro
<cassert>

assert

# if !defined(NDEBUG)
  #define assert(expr) implementation-defined
# else
  #define assert(ignore) ((void)0)
# endif

概要

式が真であることを表明する。

このマクロは、開発時に除去できるバグを見つけるために使用できる。「関数の引数がある範囲内の値でなければならない」「ある状態でこの関数を呼び出してはならない」といったことを表明することで、その関数を呼び出すユーザーに対する要件として設定できる。

このマクロは、直前の<cassert>(または<assert.h>)のインクルード時点でマクロNDEBUGが定義されていなかった場合に有効となり、NDEBUGが定義されていた場合は無効となる。

要件

パラメータの式の型はスカラ型でなければならない。

効果

  • 有効な場合:
    • パラメータの式を評価し、偽であった場合(0と等しい場合)、式をテキスト化したものに加え__FILE__, __LINE__, __func__の値を標準エラー出力に処理系定義の書式で書き込み、abort()関数を呼び出してプログラムを異常終了させる。
  • 無効な場合:
    • パラメータの式は評価はされず、何もしない。

備考

有効・無効に関わらずvoid型の式となる(文などにはならない)ので、カンマ演算子と組み合わせるなどして、式が書けるところならどこにでも記述することができる。

マクロNDEBUGは、標準C++の言語およびライブラリでは定義しない。開発環境やユーザーが定義することとなる。NDEBUGを定義せずassertを有効にした設定を「デバッグビルド」、NDEBUGを定義してassertを無効にした設定を「リリースビルド」などととして複数のビルド設定を持つ開発環境がある。

マクロNDEBUGの定義の状態を変えて<cassert>をインクルードしなおすことで翻訳単位中で有効・無効を切り替えることも可能である。

実行環境や入力によって起こりえるエラーに対するエラー処理としてこのマクロを使用すると無効化された場合に意図しない動作となることがあるので、別な手段として、例外、bool型の返却値などを検討すること。

#include <cassert>

void f(int x)
{
  // パラメータxは、正数でなければならない
  assert(x >= 0);

  // …xを使った処理…
}

int main()
{
  f(3);  // OK
  f(-1); // プログラムが異常終了する
}

出力例

prog.exe: prog.cc:6: void f(int): Assertion `x >= 0' failed.

参照

  • C++14 - 19.3 [assertions] ただしC++としての規定はほとんど無く、ほぼ参照規格であるISO C 7.2の規定によるものとなっている。
  • What does it mean for C++ that assert takes a scalar argument? パラメータの式の型についての要件は参照規格であるCの規定によるものであり、「スカラ型」がC++におけるスカラ型となるのか、あるいはCにおけるスカラ型の範囲に限定されるのか、少なくともC++14時点でははっきりしていない。