C++26のContractsがついに登場、assertを置き換えるpre/post条件

C++26 Contracts: Introduction to Preconditions and Postconditions

C++26のContractsがついに登場、assertを置き換えるpre/post条件

C++26のContracts機能がGCC 16で利用可能になった。pre()とpost()で事前条件・事後条件を関数宣言に直接記述でき、assertのように実装内に埋め込む必要がない。契約は宣言と定義の両方に書けるが、最初の宣言で確定する。評価セマンティクスはignore、observe、enforce、quick-enforceの4種類。契約は入力検証ではなく、あくまで前提条件の文書化とチェックに使う。

契約アサーションはエラー処理や入力検証に使ってはならない。関数が特定のイベントをエラーとして報告する契約上の要件を持つ場合、その処理は標準C++の制御文で行うべきであり、決して契約アサーションで行ってはならない。
  1. cogman10

    気に入らないな。

    契約を導入することで実行時エラーをコンパイル時エラーにできるなら大賛成だ。しかし、これはむしろ実行時エラーを増やすだけのように見える。その点では、本当にアサートすることを約束する(おそらく)という以外、`assert`と大差ないように思える。

    記事も大きな問題を指摘している。「重要なのは、Contractsのこの側面こそが、契約アサーションをエラー処理や入力検証に使ってはならない理由である。関数が特定のイベントをエラーとして報告するという契約内要件を持つ場合、その処理は省略不可能な標準C++制御文で行うべきであり、決して契約アサーションで行ってはならない。」

    契約が何のためにあるのかというこうした曖昧な定義は、ほぼ確実に混乱を招くだろう。入力検証ではないが、パラメータ検証だ。しかし実際には検証ではなく、エラーを出すチェックだ。でも我々が生成するエラーではない。

  2. WalterBright

    私はかつて契約の大ファンで、90年代にZortech C++コンパイラに実装したこともある:

    https://www.digitalmars.com/ctg/contract.html

    D言語でも実装した。しかし、結局あまり役に立たないことがわかった。

  3. ZuLuuuuuu

    これはEiffelプログラミング言語の「契約による設計」の概念を思い出させる:

    https://en.wikipedia.org/wiki/Design_by_contract

    https://www.eiffel.com/values/design-by-contract/introductio...

  4. Surac

    入力の検証に使えないなら、いったい何の役に立つというのか?パラメータの範囲を書き留める便利な方法。それ以上ではない。

  5. gavinray

    豆知識:何年も前に、これが標準に入るのを待つ間、C/C++にContractsを追加するGCCコンパイラプラグインを書いた。

    https://gavinray97.github.io/blog/adding-invariant-to-cpp-de...

    その記事は、GCCプラグインの書き方入門としての方が役に立ったが、少なくとも楽しかった。

  6. tsukikage

    記事には最適化のユースケースについて何も触れられていない。誰かすでに知っているかもしれないし、私が答えを探し始める前に:これは最適化段階に情報を与えることも意図しているのだろうか?おそらく if (!(some_condition)) { __builtin_unreachable(); } イディオムが達成できるのと同様に?

  7. MetaverseClub

    これを設計する際に彼らはどんなユースケースを想定していたのだろうか。

    実行時アサーションとドキュメント用なら、確かに機能するだろうが、契約なしでもおそらく問題なく機能する。

    形式検証用としては、設計は大きく外れている。

  8. randyrand

    自分だけかもしれないが、C++のような巨大で複雑な言語は相変わらず魅力が薄いように思える。

    手でコードを書くなら、美しく快適な言語への要求はかつてないほど大きい。

この日のほかの記事

2026-10-15