Constexpr variable 'a' must be initialized by a constant expression
constexprで宣言した関数やクラス、テンプレートを利用すると上記の様なエラーが稀に発生することがある。
原因
constexprの要件を満たしていない
constexprの要件・条件を満たさないコードを書いてしまうと本エラー発生する。
構文エラーによる弊害
constexpr関数/テンプレート内で不正な構文を使用してしまった際にも本エラーが発生する。
構文エラーだけでなく警告(ワーニング)にも注意する必要がある。
具体的な原因
非初期化変数の自己代入
未初期化の変数を自身に代入すると警告が発生するため注意したい。
// 警告: Variable 'a' is uninitialized when used within its own initialization
int a = a;
// 警告されない
int a = a = 0;
for (int i = i = 0; i < 10; i++);
int a = a;
は基本的にエラーメッセージとして表示されるが、int a = a = 0;
は警告されないため注意したい。警告はされなくとも、constexpr側の例のエラーは発生してしまう。このパターンは原因の特定が困難である。
非constexpr関数の利用
constexpr関数内で呼び出した関数やクラスがconstexprに対応していないと、例のエラーの原因になる。事前に以下のエラーメッセージが発生しているはずである。
Constexpr function never produces a constant expression
上記のエラーはconstexpr関数の定義開始位置で発生するため、真のエラー発生箇所の特定は難しくなる傾向にある。
// constexpr非対応の関数
int add_(int a, int b) { return a + b; }
// エラー:Constexpr function never produces a constant expression
constexpr int add(int a, int b) {
return add_(a, b);
}
int main() {
// エラー:Constexpr variable 'a' must be initialized by a constant expression
constexpr int a = add(1, 2);
}
constexpr関数内で呼び出しているadd_関数がconstexprに対応していないためエラーとなっている。