表明
表明（ひょうめい、assertion）とは、プログラミングにおける概念のひとつであり、そのプログラムの前提条件を示すのに使われる。アサーションとも呼ばれる。表明は、プログラムのその箇所で必ず真であるべき式の形式をとる。多くの言語ではそのような前提条件のチェックに表明を使用するが、設計上の判断を文書化するのに使う場合もある。表明が偽となった場合、プログラムにバグが潜在していることを示している。これを「表明違反; assertion failure」と呼ぶ。表明を言語構文や標準ライブラリとしてサポートするプログラミング言語も存在する。
プログラマは、開発過程でソースコードに表明を追加する。デバッグを単純化し、問題を早期に検出するためである。表明違反はバグを示していることが多いため、表明の実装では問題の元を示すために追加情報を表示するようになっていることが多い（ソースコードのファイル名と行番号、スタックトレースなど）。ほとんどの実装では、そのプログラムの実行が即座に停止する。
例えば、次の疑似コードには2つの表明が含まれている。
codice_1 と codice_2 が表明であり、実行時のその時点でいずれも真である。
この例では、アントニー・ホーアが1969年の論文で採用した表明の記法を使っている。この記法は主なプログラミング言語では採用されていない。しかし、実行時にチェックされない表明としてコメントにこの記法で書いておくことはできる。例えばC/C++では次のようになる。
コメント内の表明を括弧で囲んでおくことで、他の通常のコメントと区別しやすくなる。
Eiffelのような言語では、表明は設計工程の一部である。CやJavaでは実行時に前提条件をチェックするだけである。いずれの場合も実行時に正当性をチェックすることができるが、最終的には抑止されることが多い。
表明を仕様書の一種と見ることもできる。コードの部分が動作する前に期待される状態（事前条件）を記述し、そのコードを実行した後に期待される状態（事後条件）を記述する。また、クラスの不変条件を記述することもできる。Eiffelではそのような表明は言語に組み込まれており、そのクラスの仕様書の自動生成に使用される。これは契約プログラミングの重要な部分でもある。
この手法は、契約プログラミングを明確にはサポートしていない言語でも利用価値がある。コメントではなく表明を使用する利点は、表明がプログラムの実行毎にチェックされる点である。表明が真でなくなると、エラーが表示される。これによりコードの実装が表明とずれてしまった場合を早期に検出する。これはつまり、コメントとコードの内容の不一致の問題と同じである。
表明はプログラマが前提条件としていたことがプログラム実装中にも保持され、プログラム実行時でも正しいことを保証するのに使われる。例えば、以下のJavaコードを見てみよう:
Javaでは codice_3 は剰余演算子である。その第一オペランドが負であった場合、演算結果も負となる。ここでプログラマは codice_4 が負でないという前提でコーディングしており、2 で割った剰余は常に 0 か 1 だと考えている。表明（assert）は、その前提条件を明確に示している。codice_5 が負数を返す可能性があるなら、これはプログラムのバグとなる可能性がある。
この技法の主な利点は、問題が発生したときにそれを即時かつ直接的に検出できる点であり、後から検出しても様々な副作用によって真の原因がなかなかつかめないことがある。表明違反はコード上の位置を表示することが多いので、煩雑なデバッグ作業なしで問題点を即座に発見することができる。
表明は決して実行されないと見なされている箇所に置かれることもある。例えば、C、C++、Javaのような言語で、codice_6 文の codice_7 節に表明を置くことがある。プログラマが予期しない状態が発生した場合、実行をそのまま続けるのではなく、エラーを発生させてプログラムを停止させるのである。
Javaでは、表明はcodice_8文としてバージョン 1.4 から言語の一部となった。表明違反は codice_9 を発生させる。Cでは標準ヘッダファイル codice_10 で codice_11 マクロが定義されており、codice_12シンボルが定義されていない場合に有効になる。表明が失敗した場合、エラーを表示してプログラムを停止させるようになっているのが一般的である。C++の標準では codice_13 というヘッダを必要とするが、ライブラリによってはC言語同様の codice_10 が使用可能となっている。
表明はメモリの内容を書き換えてしまったり、スレッドの動作タイミングを変えてしまうなどの副作用を持つ危険性がある。表明はプログラム本体への副作用を生じないよう注意深く実装する必要がある。
開発中、プログラマは表明を入れた状態でプログラムを実行する。表明違反が発生すると、プログラマに即座に問題が通知される。ほとんどの表明の実装ではプログラムの実行も停止する。プログラムがそのまま実行を続けてしまうと問題の原因を究明することが困難となる可能性が高い。表明違反で表示される情報（違反発生箇所やスタックトレース）を使えば、プログラマは容易に問題を解決できる。このようにして表明はデバッグ工程を単純化する。
コンパイル時にチェックされる表明は静的表明と呼ばれる。静的表明はコンパイル時のテンプレートメタプログラミングに特に有効だが、C言語でも表明違反となったときのみ不正なコード（コンパイルエラーとなるコード）が導入されるようにして静的表明を実装可能である。例えば、C言語では次のように静的表明を実装できる。
codice_15 が偽と評価されると、switch文の2つ目のラベルの値はゼロとなるため、コンパイラは2つのcaseラベルが同じ値だとしてエラーを検出する。なお、指定する式はコンパイル時に値が定まるものでなければならない。例えば codice_16 といった式である。また、関数定義内でないとswitch文が出現しただけでコンパイルエラーになるので、関数内でしか使えない。
もう1つのC言語でよく知られている静的表明の実装として、次の方式がある。
codice_15 が偽と評価されると、配列の長さが負になるため、このコードはコンパイルされなくなる。たとえコンパイラが負のサイズの配列を許したとしても、初期値（codice_18 の部分）を設定しようとした時点で問題に気付くだろう。
これを何度も使用するには、配列名がそれぞれ別々でなければならない。のコンパイラにはプリプロセッサに __COUNTER__ というマクロ定義があり、出現の度に増加する数を返すので、それを名前に含めればよい。
D言語は静的表明 codice_19 をサポートしている。また、C++ではC++11において codice_20 が導入された。C言語でもC11規格で codice_21 が導入された。
表明は有効化/無効化を切り替えられるよう多くの言語で実装されている。表明は本来、開発ツールであるため、最終テストおよびリリース時には無効化する。したがって有効化時/無効化時の違いがプログラムの意味的な違いを生じないことが前提にある。換言すれば、表明は副作用を持っていてはならない。
CやC++を含む多くの言語では、表明は、リリースコンパイル時にプリプロセッサによって完全に除去される。Javaでは、表明を有効化する場合、実行時にオプションの指定を必要とする。オプションの指定がない場合、表明は無視される。
表明とエラー処理ルーチンを区別することには意味がある。表明は論理的にありえない状況をチェックするのに使うべきである。もし、「ありえない」ことが起きたとしたら、根本的に何かが間違っていたということである。エラー処理は通常発生しうるエラーを処理する（もちろん、一部の状況はほとんど「ありえない」かもしれない）。表明をあらゆるエラー処理に使用するのは賢明ではない。表明ではエラーからの復旧が考慮されておらず、表明違反は無条件でプログラムを停止させてしまう場合がほとんどである。表明はユーザー向けのエラーメッセージも表示しない。
エラー処理に表明を使っているC言語の例を以下に示す。
int *ptr = malloc(sizeof(int) * 10);
assert(ptr != NULL);
// use ptr
ここで、プログラマは codice_22 が codice_23 を返す場合があることに気づいている（メモリを確保できなかった場合）。オペレーティングシステムは codice_24 が常に成功することは保証していない。したがってプログラムはメモリ確保失敗に対処すべきである。この例では表明は最良の選択ではないだろう。というのも、malloc の失敗は論理的にありえないことではないからである。実際には滅多に発生しないが、設計上考慮すべき可能性である。しかし、このような表明にも利点がある。つまり、プログラマが自分の意思で malloc のエラーに対処するコードを書かない選択をしたことを他の人々に知らしめているのである。
表明の引数である式の副作用に依存するという間違いをすることもある。表明は条件の評価（バグがないことの確認）に使われるものであって、全く実行されないこともあることを常に念頭に置いておく必要がある。最終的にプログラムに問題がないと判断すれば表明を抑止する可能性がある。
例えば、次のようなC言語のプログラムがあるとする。
一見すると、codice_24 の値を codice_26 に代入して、同時に codice_23 かどうかをチェックするという賢いコーディングに見えるかもしれない。しかし、codice_24 呼び出しと codice_26 への代入は副作用を伴い、その副作用はプログラム本体で必須なものである。コンパイル時に codice_12 というシンボルを定義すると codice_31 は除去されるので、codice_32 が呼び出されなくなり、codice_26 が初期化されずに使われることになる。結果として未定義動作を引き起こす。
プログラムの正しさを証明する手段として表明の概念を最初に提案したのはアラン・チューリングである。1949年6月24日、ケンブリッジ大学で行った "Checking a Large Routine" と題した講演で「大きなルーチンが正しく動作していると確認するにはどうしたらよいだろうか? 確認する人物に多大な負担をかけないようにするには、プログラムの全体としての正しさを容易に確認できるようプログラマが個別に確認可能な明確な「表明」("assertions") をいくつもするべきである」と述べている。