NF

地方で働くプログラマ

やさしいconstexpr(1)

自分(が知らない人に説明する)用
長いうえに情報量少ないです

constexprってなに

なにがうれしいの

色々あるみたいだけど、一番単純そうな例を。
構造体になにかのサイズが入っていて、そのサイズ分の配列を宣言したい状況を考える。

struct X { int size; };
int main() {
    const X x = {10};
    int arr[x.size] = {1};
}

これは、実装した人の期待に反してコンパイルエラーになる。(gcc13.0で-pedantic -Werrorを指定してます)

$ g++ -std=c++11 -O0 -pedantic main.cpp
main.cpp: In function 'int main()':
main.cpp:4:9: warning: ISO C++ forbids variable length array 'arr' [-Wvla]
    4 |     int arr[x.size] = {1};

しかし、constではなくconstexprを使うとエラーにならない。うれしいね。

struct X { int size; };
int main() {
    constexpr X x = {10};
    int arr[x.size] = {1};
}

おわり



補足:なんでconstとconstexprで違いが出るの

C++には「コンパイル定数」と「実行時定数」の2種類があって、intのような整数型以外のconst変数は「実行時定数」になる。(※)
対して、固定長配列のサイズは「コンパイル定数」しか指定できないと決まっている。
なので、最初の例はコンパイルエラーになるが、次の例はコンパイルが通る。


※整数型以外は「コンパイル定数」にならないので、例えば

    const int size = 10;
    int arr[size] = {1};

コンパイルが通るけど

    const float size = 10;
    int arr[(int)size] = {1};

コンパイルエラーになる。(こんな事しないだろうけど)
これも同じく、size変数をconstexprにするとコンパイルが通る。