如果数据未按给定偏移量对齐,为什么 BitConverter.ToInt32 一次读取一个字节?

Jam*_* Ko 6 .net c# pointers unsafe memory-alignment

很抱歉标题令人困惑,但我想不出更好的方法来解释它。

最近在浏览源码BitConverter时,发现了一段奇怪的代码:

public static unsafe int ToInt32(byte[] value, int startIndex)
{
    fixed (byte* pbyte = &value[startIndex])
    {
        if (startIndex % 4 == 0) // data is aligned 
            return *((int*)pbyte);
        else
        { 
            if (IsLittleEndian)
            {  
                return (*pbyte) | (*(pbyte + 1) << 8)  | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); 
            } 
            else
            { 
                return (*pbyte << 24) | (*(pbyte + 1) << 16)  | (*(pbyte + 2) << 8) | (*(pbyte + 3));                         
            } 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

pbyte在这种情况下,转换到(第 6 行)如何会int*违反数据对齐?为了简洁起见,我省略了它,但代码具有正确的参数验证,因此我很确定它不会是内存访问冲突。铸造时会失去精度吗?

换句话说,为什么代码不能简化为:

public static unsafe int ToInt32(byte[] value, int startIndex)
{
    fixed (byte* pbyte = &value[startIndex])
    {
        return *(int*)pbyte;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑: 是有问题的代码部分。

Joe*_*nta 1

我敢打赌,这与 C# 规范 5.0 版本中的 \xc2\xa718.4 的这一部分有关(强调我的):

\n\n
\n

当一种指针类型转换为另一种指针类型时,如果生成的指针未针对所指向的类型正确对齐,则在取消引用结果时,行为未定义。

\n
\n\n

在“未对齐”情况下进行字节复制是为了避免依赖显式未定义的行为。

\n