2016-02-08 5 views
9

問題のよう: のは、私がこのようなコードの小片を持っているとしましょう:g++ -g -O2でコンパイルさC++揮発物、不揮発メンバー

#include <iostream> 
    using namespace std; 

    struct foo { 
     int a; 
     foo() : a(12) {}; 
    }; 

    int 
    main() 
    { 
     volatile foo x; 
     return 0; 
    } 

それはx初期化が離れて最適化されていること、が判明しました。しかし

その1:

#include <iostream> 
    using namespace std; 

    struct foo { 
     volatile int a; 
     foo() : a(12) {}; 
    }; 

    int 
    main() 
    { 
     volatile foo x; 
     return 0; 
    } 

は、コンストラクタを呼び出します。

コード内の変数(つまり、cout << foo.a << endl;)を使用しようとすると、アセンブリ出力はどちらの場合も同等です。それは完全に離れて最適化されますので、最初のケースで

、全く構造体へのアクセスがありません:

は、私は、それが右の次もらえます。

構造体のフィールドは、構築中にも変更可能なフィールドとして示されているため、foo()は何であれ呼び出されます。

を追加しました:予想通り while(foo.a--);作品のようなものを呼び出すと、それは実際に代わりに最適化中に結果に置き換え/削除されるので起こり、これには、揮発性が、実際に継承されているようで、まだ: 私は上記のコードをいじる試してみましたctorはこの奇妙な(あるいは少なくとも予期しない)最初の方法で動作します。

EDIT番号2:

私が打ち鳴らすとMSVCでそれをチェックし、それはgccのと同じように動作します。

+0

私にバグのように見えます。 "** [basic.type.qualifier] /(1.2)** A * volatile *オブジェクトは、そのようなオブジェクトのサブオブジェクトである' volatile T'型のオブジェクトです... "したがって、両方の例で' foo。 aは揮発性のオブジェクトであり、その操作は観察可能な副作用であり、最適化してはいけません。 –

+0

@IgorTandetnik私は、揮発性の自動変数がどのように観測可能であるかは本当に理解できませんでした。コンパイラのバグであることを受け入れることで、実際に何かを壊す可能性があることを理解するのは難しいです(また、コンパイラがこの可能性にどのように対処するのか見えにくく、オプティマイザ*は 'foo '' foo'がvolatileとしてインスタンス化された場合に個別に最適化する必要はありません)。 –

答えて

2

次のように私の理解では(と私はそれについて確認していない)である:

C++ volatileキーワード軍コンパイラではメモリーに一見冗長なロードとストアを最適化することではない、あなたは、このようなサンプルコード持っているつまり場合:

xは、いくつかのAを指している可能性があるため、これは

int x = 6; 

int x = 5; 
x = 6; 

はそれに変更されることはありませんあなたがあなたのプログラムで本当にそれを読んでいない間に他の人が読んでいるメモリ内のddress(ある種のメモリアドレスに書き込むことによって、USARTを介していくつかのコンフィギュレーションをマイクロコントローラに送ることを想像してください。コンパイラがこのメモリへの書き込みを最適化すると、プログラム全体が誤動作する)。 1は覚えておく必要があります

もう一つは、クラスのインスタンスがvolatile指定子で宣言されたとき(イゴールTandetnikは、C++標準を参照して、コメントで指摘したように)、そのメンバーは、この指定を継承していることです。しかし、volatileの動作を得るためには、volatileとマークされたメンバ関数を呼び出す必要があります。これは、メンバ関数をconst(これを参照してください:http://www.devx.com/tips/Tip/13671)と同様です。AFAIKのctors/dtorsはvolatileというキーワード(Defining volatile class objectのように)でマークできないため、コードを少し変更する必要があります(おそらくctor内のvolatileメンバー関数を呼び出しても問題ありませんが、これは単なる推測です)。

+0

Ctorをvに指定することはできません。ここのケースのように思えますが、より明示的に標準で説明されていることを確認したいのですが、それだけです。私は質問にいくつかの情報を追加しました。 – alagner

+0

はい、私は "AFAIK ctors/dtorsには揮発性のキーワードでマークすることはできません"と書いたと思います。それともsth else? –

関連する問題