名前空間
変種
操作

定数式

From cppreference.com
< c‎ | language

いくつかの種類の式は、定数式として知られています。

目次

[編集] プリプロセッサ定数式

#if または #elif に続く式は、以下に展開される必要があります。

文字定数は、#if 式で評価される場合、ソース文字セット、実行文字セット、または他の実装定義の文字セットで解釈されることがあります。

#if 式での整数演算は、符号付き型にはintmax_t、符号なし型にはuintmax_tのセマンティクスを使用して実行されます。

(C99以降)

[編集] 整数定数式

整数定数式は、以下のもののみで構成される式です。

  • _Alignof(C23まで)alignas(C23以降) 演算子
(C11 以降)
  • 整数型であるか、算術型でありキャストの直接的なオペランドである名前付きおよび複合リテラル定数
(C23以降)

整数定数式はコンパイル時に評価されます。以下の文脈では、整数定数式として知られる式が必要です。

(C99以降)
(C11 以降)
  • ビット精度整数型(_BitInt(N))のビット数N
(C23以降)

[編集] 静的初期化子

静的およびスレッドローカルな記憶期間を持つオブジェクトの初期化子で使用される式、または constexpr 記憶クラス指定子で宣言されたもの(C23以降)は、文字列リテラルであるか、以下のいずれかである式でなければなりません。

1) 算術定数式。これは、以下のものから構成される任意の算術型の式です。
(C11 以降)
  • 算術型の名前付きまたは複合リテラル定数
(C23以降)
2) ヌルポインタ定数 (例: NULL)
3) アドレス定数式。これは、
  • ヌルポインタ
  • 静的記憶期間を持つオブジェクトまたは関数指定子を指定する左辺値であり、以下のいずれかの方法でポインタに変換されたもの
  • 単項アドレス演算子を使用する
  • 整数定数をポインタにキャストする
  • 配列からポインタ、または関数からポインタへの暗黙的な変換
4) ある完全なオブジェクト型のアドレス定数式に、整数定数式を加算または減算したもの
5) 名前付き定数。これは、以下のいずれかである識別子です。
  • 列挙定数
  • 事前定義定数(truefalsenullptrのいずれか)
  • 記憶クラス指定子 constexpr で宣言されており、オブジェクト型を持つもの
または、構造体または共用体型の名前付き定数に、再帰的に適用される . メンバアクセス演算子を適用する後置式。
6) 複合リテラル定数。これは、
  • 記憶クラス指定子 constexpr を持つ複合リテラル
  • 構造体または共用体型の複合リテラル定数に、再帰的に適用される . メンバアクセス演算子を適用する後置式。

構造体または共用体定数は、それぞれ構造体または共用体型を持つ名前付き定数または複合リテラル定数です。メンバアクセス演算子 . が共用体定数のメンバにアクセスする場合、アクセスされるメンバは、共用体定数の初期化子によって初期化されるメンバと同じでなければなりません。

(C23以降)
7) 実装が受け入れる他の形式の定数式。

整数定数式とは異なり、静的初期化子式はコンパイル時に評価される必要はありません。コンパイラは、そのような初期化子をプログラム起動前に呼び出される実行可能コードに変換することができます。

static int i = 2 || 1 / 0; // initializes i to value 1

浮動小数点静的初期化子の値は、実行時に実行される同じ式の値よりも精度が低いことはありませんが、より良い場合があります。

[編集] 浮動小数点定数式

静的初期化子で使用されない浮動小数点型の算術定数式は、常に実行時と同様に評価され、現在の丸めFENV_ACCESSがオンの場合)の影響を受け、math_errhandlingで指定されたエラーを報告します。

void f(void)
{
#pragma STDC FENV_ACCESS ON
    static float x = 0.0 / 0.0; // static initializer: does not raise an exception
    float w[] = { 0.0 / 0.0 };  // raises an exception
    float y = 0.0 / 0.0;        // raises an exception
    double z = 0.0 / 0.0;       // raises an exception
}

[編集] 注釈

式がその型で表現できない値に評価される場合、定数式として使用することはできません。

実装は他の形式の定数式を受け入れる場合があります。ただし、これらの定数式は整数定数式、算術定数式、またはアドレス定数式とは見なされないため、これらの種類の定数式を必要とする文脈で使用することはできません。例えば、int arr[(int)+1.0];はVLAを宣言します。

[編集] 参照

  • C23標準 (ISO/IEC 9899:2024)
  • 6.6 定数式 (p: TBD)
  • C17標準 (ISO/IEC 9899:2018)
  • 6.6 定数式 (p: 76-77)
  • C11標準 (ISO/IEC 9899:2011)
  • 6.6 定数式 (p: 106-107)
  • C99標準 (ISO/IEC 9899:1999)
  • 6.6 定数式 (p: 95-96)
  • C89/C90標準 (ISO/IEC 9899:1990)
  • 3.4 定数式

[編集] 関連項目

C++ documentation for 定数式
English 日本語 中文(简体) 中文(繁體)