Volatileとmutableの違いについて質問があります。 2つとも変更できることを意味していることに気付きました。ほかに何か?それらは同じものですか?違いは何ですか?それらはどこに適用できますか?なぜ2つのアイデアが提案されているのですか?別の方法でそれらを使用する方法?
どうもありがとう。
mutable
フィールドは、const
ポインターまたは参照を介してアクセスされるオブジェクト、またはconst
オブジェクト内でも変更できるため、コンパイラーはR/Oメモリ。 volatile
の場所は、コンパイラーが知らないコード(たとえば、カーネルレベルのドライバー)によって変更できる場所です。したがって、コンパイラーは、たとえば値がそのレジスタに最後にロードされてから「変更されていない可能性がある」という無効な仮定の下で、その値のレジスタ割り当て。非常に異なる種類の無効な最適化を停止するために、コンパイラに非常に異なる種類の情報が提供されます。
mutable
:mutableキーワードは、囲むconstステートメントをオーバーライドします。 constオブジェクトの可変メンバーは変更できます。
volatile
:volatileキーワードは実装に依存する修飾子であり、変数を宣言するときに使用され、コンパイラーがそれらの変数を最適化できないようにします。揮発性は、コンパイラが実行する可能性のある最適化と競合する可能性のある、予期しない方法で(つまり、割り込みを介して)値が変化する可能性がある変数で使用する必要があります。
それらは間違いなく同じものではありません。 Mutableはconstと対話します。 constポインターがある場合、通常はメンバーを変更できません。 Mutableは、そのルールの例外を提供します。
一方、揮発性は、プログラムによる変更とはまったく関係ありません。これは、コンパイラが制御できない理由でメモリが変更される可能性があるため、コンパイラは毎回メモリアドレスを読み書きする必要があり、レジスタにコンテンツをキャッシュできないことを意味します。
違いの大雑把だが効果的な考え方は次のとおりです。
mutable
とマークされた変数は、const
と宣言されたメソッドで変更することができます。
volatile
とマークされた変数は、コードが指示するたびに変数を読み書きする必要があることをコンパイラーに指示します(つまり、変数へのアクセスを最適化できません)。
Volatileは、マルチスレッドアプリケーションを扱うときにも非常に便利です。つまり、メインスレッド(main()が存在する場所)があり、変数 "app_running"がtrueである間スピンを続けるワーカースレッドを生成します。 main()は、「app_running」がtrueまたはfalseであるかどうかを制御するため、volatile属性を「app_running」の宣言に追加しない場合、コンパイラがセカンダリスレッドによって実行されるコードの「app_running」へのアクセスを最適化する場合、main( )は「app_running」をfalseに変更する可能性がありますが、値がキャッシュされているため、セカンダリスレッドは実行を続けます。 LinuxとVisualC++でgccを使用して同じ動作を確認しました。 「app_running」宣言に含まれる「volatile」属性が問題を解決しました。したがって、これは、そのような変数の値を変更する際にハードウェア割り込みやカーネルが呼び出されないシナリオです。