2012-01-21 5 views
4

constのいずれの場合でも、volatileを使用することができますか?constはどこでも使用できますか?

volatile dummy_class 
volatile dummy_class& 
dummy_class volatile* 
dummy_class *volatile 
dummy_class volatile *volatile 

constが含まれている場合、これらは同じセマンティクスがvolatileのために適用されます、すべての明確な例がありますか?

+1

私は答えがイエスだと信じています。答えとして投稿してください。上記のそれぞれの証拠をスタンダードから提供する必要があり、それらはさまざまなセクションに分散しています。 –

答えて

2

これはセクション3.9.3 CV-修飾子C++ 11ドラフトn3290から

3.9.1及び3.9.2で述べたタイプのCV-非修飾型です。 const修飾バージョン、揮発性の修飾バージョン、および:CV-非修飾 完全または不完全なオブジェクト型であるか無効である各タイプ(3.9)は、そのタイプの対応する3つのCV修飾バージョンを有しますconst-volatile修飾バージョン。オブジェクト というタイプ(1.8)には、オブジェクトの作成時に指定されたcv-qualifierが含まれています。 decl-specifier-seqにconst指定子 が存在すると、const修飾されたオブジェクト型のオブジェクトが宣言されます。そのようなオブジェクトはconstオブジェクトと呼ばれます。 decl-specifier-seqにvolatile指定子があると、volatile修飾されたオブジェクト型のオブジェクトが宣言されます。 このようなオブジェクトは揮発性オブジェクトと呼ばれます。 decl-specifier-seqに両方のcv-qualifierが存在すると、const-volatile修飾されたオブジェクト型のオブジェクト が宣言されます。そのようなオブジェクトはconst volatileオブジェクトと呼ばれます。型のcv修飾型または cv非修飾型は、異なる型です。しかし、彼らは同じ表現を持たなければならないと 配置要件(3.9)0.51

のでconstvolatileはおそらく接続詞で、同じスポットで使用することができます。

const修飾クラスオブジェクトの各非静的、が非可変、非参照データメンバ:そのセクションの

パラグラフ3は、それらがクラスオブジェクトに適用される方法のわずかな違いを指摘しますvolatile修飾クラスオブジェクトの各非静的非参照データメンバは揮発性修飾され、 はconst volatileクラスのメンバと同様にconst修飾されます。 cv修飾子を持つ関数型については、8.3.5および9.3.2を参照してください。

しかしそれはかなり論理的です。

volatile -qualifiedオブジェクトがとして-IFルールの厳格な要件があり、すなわち:揮発性のオブジェクトへ

のアクセスは、抽象機械の規則に従って厳密に評価されます。

ボラティリティがconstと同じ方法でオブジェクトに付加されます:非静的メンバ関数(§9.3.1)について

dummy_class volatile* // non-volatile pointer to volatile object 
dummy_class *volatile // volatile pointer to non-volatile object 
dummy_class volatile *volatile // volatile pointer to volatile object 

を:

非静的メンバ関数はconst、volatile、またはconst volatileと宣言できます。 これらのcv修飾子 は、このポインタ(9.3.2)のタイプに影響します。それらはメンバ関数の関数型(8.3.5)にも影響します。 const宣言されたメンバ関数はconstメンバ関数で、volatile宣言されたメンバ関数は volatileメンバ関数と宣言されたメンバ関数const volatileはconst volatileメンバ 関数です。

したがって、const-nessのようなボラティリティは、関数内のthisに適用されます。

constでもvolatileも、静的メンバー関数には適用できません。

6

ほぼ。どちらもcv-qualifiersであり、他ができるところではほぼどこでも使用できます。彼らはC++の文法に表示されます唯一の場所はここにある:

CV-修飾子:
        const
        volatile

や文法の残りの部分としてそれらを参照しますcv-qualifier

を使用することができますCV-修飾子がどこにある一つの場所あなたが言及しなかった。なお:

struct X { 
    void f() const; 
    void g() volatile; 
    void h() const volatile; 
}; 

は、後の使用のためにhttp://drdobbs.com/cpp/184403766を参照してください。

stuct X { 
    mutable const int x; // error 
    mutable volatile int y; // valid 
}; 

標準のint関連する場所は[dcl.stc]です::

しかし、はあなたがに似constmutableを組み合わせることはできませんルールがあります変更可能な指定子はクラスデータメンバ(9.2)の名前にのみ適用でき、constまたはstatic [...]と宣言された名前には適用できません

+0

どこでも「揮発性」のオーバーロードを提供することはありません。揮発性は、プリミティブ型に対してのみ最も有用であり、その存在によって悩まされることはめったにありません。 –

1

任意の変数は、constまたはvolatile(またはその両方)と宣言できますが、セマンティクスは異なります。

キーワードconstは、変数が定数であることを示します。 volatileキーワードは、何も割り当てていなくても変数の内容が変更されている可能性があることを示します。あなたは

int a = ...; 
int b = ...; 
int sum1 = (a + b) * 2; 
int sum2 = (a + b) + 16; 

コードのこの部分を持っているし、あなたのコンパイラの最適化を有効にした場合

例えば、コンパイラは、このに、以前のコードを最適化することができます

int a = ...; 
int b = ...; 
int temp = a + b; 
int sum1 = temp * 2; 
int sum2 = temp + 16; 

この最適化が原因で発生しますコンパイラはsum1とsum2の計算時にaとbの値が変化しないと仮定しているため、a + bは変化しません。aまたはbをvolatileと宣言すると、この仮定は否定されます。つまり、コンパイラは+ bを毎回計算し、一時的な場所に格納しないコードを生成します。これは、aまたはbを宣言することにより、aまたはb(したがって、a + b)が2つのステートメントの実行の間に変更された可能性があることを示すためです。

volatileはマルチスレッドアプリケーションやメモリマップされたI/O(ハードウェアとの通信にシステムメモリを使用している)を使用する場合には役に立たないキーワードのようです。例えば、ゲームボーイアドバンスでは、一度にどのキーが押されたかを判断するために、特定のメモリ位置を読み取らなければならない。その特定のメモリ位置へのポインタをvolatileと宣言すると、毎回その特定のデータをメモリから読み取ることが常に保証されます。

+0

コンテキストに依存して、 'const'は' constant'より 'read-only'に近いです。 –

+0

@OliCharlesworth 'const_cast'が存在すると、constが関与しているときに「読み取り専用」という概念が壊れやすくなります。私は読み取り専用のもののためにconstexprを使用したいと思います。 – rubenvb

1

C++ 2003では、static int volatileのクラスのメンバーを定義することはできませんが、static int constのメンバーでこれを行うことができます。後者は定数式になり、アドレスや参照が必要ない限りあなたは大丈夫でしょう。 C++ 2011の場合、クラス定義のメンバを初期化できるため、これが変更されたかどうかはわかりませんが、静的メンバに拡張されているかどうかはわかりません。

関連する問題