最終更新日時: 2025年07月10日 10時26分30秒 (JST)
Koichi Murase が更新

履歴 編集

# 定数式内での非リテラル変数、静的変数・スレッドローカル変数およびgotoとラベルの存在を許可する [P2242R3](C++23)

このページはC++23に採用された言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

## 概要

`constexpr`関数が非リテラル変数、静的変数・スレッドローカル変数およびgoto文とラベルを含むことを許可する。

ただし、これをコンパイル時に評価した場合、従来通りエラーとなる。 これらを含むコードパスは実行時にのみ通過するようにしなければならない。

## この機能が必要になった背景・経緯

これまでは、`constexpr`関数内には非リテラル変数、静的変数・スレッドローカル変数およびgoto文とラベルが含まれてはならなかった。 これは、`constexpr`関数が定数式実行できない要素を含んではならないという意味で、理にかなった制限であった。

しかし、C++20で`std::is_constant_evaluated`によって定数式実行されるコードパスと実行時に通るコードパスを分けることが可能になり、状況が変化した。 定数式実行できないコードとはいえ、実行時にのみ通りコンパイル時には通らないコードパスに含まれていた場合にもプログラムが不適格となる、というのは直観に反する。

よって、コンパイル時に評価されない限りにおいて、`constexpr`関数内に非リテラル変数、静的変数・スレッドローカル変数およびgoto文とラベルを含むことが許可されることとなった。

ただし、`constexpr`内に存在することが許可されたものの定数式として評価できるわけではないので、これらの機能は依然としてコンパイル時に使用することはできない。

## 関連項目

- C++20 - constexpr関数内でのtry-catchブロックを許可
- C++20 - constexpr関数内で未評価のインラインアセンブリを許可することによる組み込み関数のconstexpr有効化
- C++23 - `constexpr`関数内での`static constexpr`変数を許可

## 参照

- P2242R3 - Non-literal variables (and labels and gotos) in constexpr functions