問題のよう: のは、私がこのようなコードの小片を持っているとしましょう: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のと同じように動作します。
私にバグのように見えます。 "** [basic.type.qualifier] /(1.2)** A * volatile *オブジェクトは、そのようなオブジェクトのサブオブジェクトである' volatile T'型のオブジェクトです... "したがって、両方の例で' foo。 aは揮発性のオブジェクトであり、その操作は観察可能な副作用であり、最適化してはいけません。 –
@IgorTandetnik私は、揮発性の自動変数がどのように観測可能であるかは本当に理解できませんでした。コンパイラのバグであることを受け入れることで、実際に何かを壊す可能性があることを理解するのは難しいです(また、コンパイラがこの可能性にどのように対処するのか見えにくく、オプティマイザ*は 'foo '' foo'がvolatileとしてインスタンス化された場合に個別に最適化する必要はありません)。 –