C# 对.NET中未对齐字段的读写是否一定是原子的?

C# 对.NET中未对齐字段的读写是否一定是原子的?,c#,.net,atomic,memory-alignment,C#,.net,Atomic,Memory Alignment,C#规范(和)中有一段关于读写的原子性: 12.5变量引用的原子性 以下数据类型的读写应为原子型:bool、char、byte、sbyte、short、ushort、uint、int、float和引用类型。此外,前面列表中具有基础类型的枚举类型的读写也应是原子的。其他类型(包括long、ulong、double和decimal)以及用户定义类型的读写不需要是原子的 但我很难想象这是真的。例如,我可以使用布局结构,并强制字段不对齐: // sizeof(MyStruct) == 9 [Struct

C#规范(和)中有一段关于读写的原子性:

12.5变量引用的原子性

以下数据类型的读写应为原子型:bool、char、byte、sbyte、short、ushort、uint、int、float和引用类型。此外,前面列表中具有基础类型的枚举类型的读写也应是原子的。其他类型(包括long、ulong、double和decimal)以及用户定义类型的读写不需要是原子的

但我很难想象这是真的。例如,我可以使用布局结构,并强制字段不对齐:

// 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上)?不管怎样,你有任何来源来支持这一点吗?

我认为你是对的。。。在某些情况下,如果您故意不按自己的方式操作,系统将无法按照语言规范进行操作。重要的是,在第I部分第12.6.6节中明确了这一点:

符合要求的CLI应保证对正确对齐的内存进行读写访问 不大于本机单词大小(类型native int的大小)的位置是原子的 (参见§I.12.6.2)当对一个位置的所有写访问都具有相同的大小时。原子写入应 除了写下的内容外,不要改变其他内容除非显式布局控制(请参见 分区II(控制实例布局))用于更改默认行为,数据元素编号 应正确对齐大于自然字号(本机int的大小)的字号。对象 参考资料应视为以本机字号存储


(粗体强调;斜体在规范中。)

乔恩当然是正确的;如果你故意破坏对齐,那么你也故意破坏原子性。如果你那样做很痛,那就不要那样做。