对于令人困惑的标题感到抱歉,但我无法想出更好的解释方法。
最近浏览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是相关代码的一部分。
答案 0 :(得分:1)
我敢打赌,这与C#规范5.0版本中的§18.4的这一部分有关(强调我的):
当一个指针类型转换为另一个指针类型时,如果生成的指针未针对指向类型正确对齐,如果取消引用结果,则行为未定义。
完成“未对齐”情况下的字节复制,以避免依赖于显式未定义的行为。