2013-03-06 8 views
6

C#の仕様(ECMA-334ISO/IEC 23270が)の原子についての段落の読み取りと書き込みました:変数の参照の.NETのアラインされていないフィールドへの読み取りと書き込みは絶対不可分なのでしょうか?

12.5不可分

は読み込み、次のデータ型の書き込みはアトミックでなければなりません。 bool、char、byte、sbyte、short、ushort、uint、int、float、および参照型のいずれかです。加えて、前のリストの基になるタイプの列挙型の読み書きもアトミックでなければなりません。 long型、ulong型、double型、decimal型、ユーザー定義型などの他の型の読み書きは、アトミックである必要はありません。

しかし、私はそれが常に真実であると想像しています。例えば、私はStructLayout attributeを使用して、構造体のレイアウト、および非整列するフィールドを強制することができます:私はこれを行うとき

// sizeof(MyStruct) == 9 
[StructLayout(LayoutKind.Sequential, Pack = 1)] 
struct MyStruct 
{ 
    public byte pad; // Offset: 0 
    public int value1; // Offset: 1 
    public int value2; // Offset: 5 
} 

は今、私はそれがあるので、intへの書き込みは、アトミックないあると思うだろう自然な境界にアラインされていない:

だから、それは間違いなく、原子(仕様が言うように)である
MyStruct myStruct = new MyStruct(); 
myStruct.value1 = 20; 

、またはそれがアトミックであることが保証されていない(例えばx86版)?いずれにしても、これをバックアップする情報源はありますか?

+2

ジョンは、もちろん、正確です。故意にアライメントを壊すと、故意に原子性が壊れてしまいます。あなたがそれをするときに痛いなら**それをしないでください**。 –

答えて

6

私はあなたが正しいと思います...あなたが故意に途中で外出すると、システムは言語仕様に従って動作しません。重要なのは、ECMA-335がパーティションIセクション12.6.6で、これは明示的になります:

準拠CLI への読み取りおよび書き込みアクセスを保証するものと適切に整列メモリネイティブワードサイズよりも大きくない 場所(型のサイズnative int)は、場所へのすべての書き込みアクセスが同じサイズの場合には、アトミック (§12.6.2参照)です。原子書き込みは、 は、書き込まれたビット以外のビットを変更しないものとする。 デフォルトの動作を変更するために、明示的なレイアウト制御( パーティションII(コントロールのインスタンスレイアウト)を参照)を使用しない場合、自然なワードサイズ(ネイティブintのサイズ)より大きいデータ要素はになります。オブジェクト の参照は、それらがネイティブワードサイズで格納されているかのように扱われなければならない。

(太字強調鉱山;イタリック体が仕様内にある。)

関連する問題