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

时间:2015-08-26 01:07:17

标签: c# .net pointers memory-alignment unsafe

对于令人困惑的标题感到抱歉,但我无法想出更好的解释方法。

最近浏览BitConverter的{​​{3}}时,我遇到了一段奇怪的代码:

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));                         
            } 
        }
    }
}

在此方案中,如何将pbyte投射到int*(第6行)违反数据对齐方式?为简洁起见,我把它留了下来,但代码有正确的参数验证,所以我很确定它不会成为内存访问冲突。铸造时会失去精度吗?

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

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

修改: the source code是相关代码的一部分。

1 个答案:

答案 0 :(得分:1)

我敢打赌,这与C#规范5.0版本中的§18.4的这一部分有关(强调我的):

  

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

完成“未对齐”情况下的字节复制,以避免依赖于显式未定义的行为。