名前空間
変種
操作

cv (const および volatile) 型修飾子

提供: cppreference.com
< cpp‎ | language
 
 
 
 

宣言されているオブジェクトまたは表されている型の定数性や揮発性を指定するために、型指定子 (宣言の文法decl-specifier-seq を含む) 内に現れます。

  • const ー 型が定数であると定義します。
  • volatile ー 型が揮発であると定義します。
  • mutable ー 非参照かつ非 const な型の非静的クラスメンバに適用し、そのメンバがそのクラスの外から見える状態に影響しないことを指定します (ミューテックス、キャッシュ、遅延評価およびアクセス計測などに対してしばしば使用されます)。 (ノート: C++ の言語構文は mutable記憶域クラス指定子として扱っていますが、記憶域クラスには影響しません。)

目次

[編集] 説明

関数型または参照型以外の任意の型 T (不完全型を含む) について、さらに3つの異なる型 (const 修飾された T、 volatile 修飾された T、 const volatile 修飾された T) が C++ の型システムに存在します。

ノート: 配列型はその要素の型と同じ cv 修飾を持つとみなされます。

オブジェクトが最初に作成されたとき、使用された cv 修飾 (宣言decl-specifier-seq または declarator の一部、または new 式type-id の一部として指定できます) は、以下のように、そのオブジェクトの定数性や揮発性を決定します。

  • const オブジェクト ー const 修飾された型のオブジェクト、または const オブジェクトの mutable でない部分オブジェクト。 そのようなオブジェクトは変更できません。 直接変更する試みはコンパイル時エラーであり、間接的に変更する (例えば非 const 型への参照やポインタを通して const オブジェクトを変更する) 試みは未定義動作です。
  • volatile オブジェクト ー volatile 修飾された型のオブジェクト、または volatile オブジェクトの部分オブジェクト、または const volatile オブジェクトの mutable な部分オブジェクト。 volatile 修飾された型の glvalue 式を通して行われたすべてのアクセス (読み書き操作、メンバ関数呼び出しなど) は、最適化の目的に対して可視な副作用として扱われます (つまり、単一の実行のスレッド内では、 volatile アクセスを最適化で除去したり、その volatile アクセスに対して先行配列または後続配列される別の可視な副作用と並び替えたりすることはできません。 これにより、 volatile オブジェクトはシグナルハンドラとの通信に適することとなりますが、別の実行のスレッドとの通信には適しません。 std::memory_order を参照してください)。 非 volatile な glvalue (非 volatile 型への参照やポインタなど) を通して volatile オブジェクトを参照する試みは未定義動作です。
  • const volatile オブジェクト ー const volatile 修飾された型のオブジェクト、 const volatile オブジェクトの mutable でない部分オブジェクト、 volatile オブジェクトの const な部分オブジェクト、または const オブジェクトの mutable でない volatile な部分オブジェクト。 const オブジェクトと volatile オブジェクトの両方として振る舞います。

cv 修飾には制約が増える順序による半順序関係があります。 型は以下のようにより多くまたはより少なく cv 修飾されていると言うことができます。

  • 無修飾 < const
  • 無修飾 < volatile
  • 無修飾 < const volatile
  • const < const volatile
  • volatile < const volatile

cv 修飾された型への参照またはポインタは、より多く cv 修飾されている型への参照またはポインタに暗黙に変換されます。 特に、以下の変換が許容されます。

  • 無修飾な型への参照またはポインタは const な型への参照またはポインタに変換できます。
  • 無修飾な型への参照またはポインタは volatile な型への参照またはポインタに変換できます。
  • 無修飾な型への参照またはポインタは const volatile な型への参照やポインタに変換できます。
  • const な型への参照またはポインタは const volatile な型への参照またはポインタに変換できます。
  • volatile な型への参照またはポインタは const volatile な型への参照またはポインタに変換できます。
ノート: 複数段のポインタには追加の制約が課されます。

cv 修飾された型への参照またはポインタをより少なく cv 修飾された型への参照またはポインタに変換するには、 const_cast を使用しなければなりません。

[編集] キーワード

const, volatile, mutable

[編集] ノート

extern 宣言されていない非ローカルかつ非 volatile な変数の宣言に使用される const 修飾子は、その変数に内部リンケージを与えます。 これは const なファイルスコープの変数が外部リンケージ持つ C とは異なります。

[編集]

int main()
{
    int n1 = 0;           // 非 const オブジェクト
    const int n2 = 0;     // const オブジェクト
    int const n3 = 0;     // const オブジェクト (n2 と同じ)
    volatile int n4 = 0;  // volatile オブジェクト
    const struct
    {
        int n1;
        mutable int n2;
    } x = {0, 0};      // mutable メンバを持つ const オブジェクト
 
    n1 = 1; // OK、変更可能なオブジェクト
//  n2 = 2; // エラー、変更可能でないオブジェクト
    n4 = 3; // OK、副作用として扱われます
//  x.n1 = 4; // エラー、 const オブジェクトのメンバは const です
    x.n2 = 4; // OK、 const オブジェクトの mutable メンバは const ではありません
 
    const int& r1 = n1; // 非 const オブジェクトに束縛された const への参照
//  r1 = 2; // エラー、 const への参照を通して変更しようとしています
    const_cast<int&>(r1) = 2; // OK、非 const オブジェクト n1 を変更します
 
    const int& r2 = n2; // const オブジェクトに束縛された const への参照
//  r2 = 2; // エラー、 const への参照を通して変更しようとしています
//  const_cast<int&>(r2) = 2; // 未定義動作、 const オブジェクト n2 を変更しようとしています
}

出力:

# x86_64 プラットフォーム上で生成される一般的な機械語コード
# (観察可能な副作用に寄与するコードのみが生成されます)
main:
    movl    $0, -4(%rsp) # volatile int n4 = 0;
    movl    $3, -4(%rsp) # n4 = 3;
    xorl    %eax, %eax   # return 0 (暗黙)
    ret

[編集] 関連項目

const 修飾子C言語リファレンス
volatile 修飾子C言語リファレンス