GSe*_*erg 2 .net c# .net-4.0 intptr pointer-arithmetic
public static IntPtr Add(
IntPtr pointer,
int offset
)
Run Code Online (Sandbox Code Playgroud)
这是伟大的,因为它应该解决所有这些问题IntPtr的数学,我们有(1,2,可能更多).
但是为什么offset int呢?
一定不是IntPtr吗?我可以很容易地想象将64位指针偏移超出int范围的值.
例如,考虑Marshal.OffsetOf:
public static IntPtr OffsetOf(
Type t,
string fieldName
)
Run Code Online (Sandbox Code Playgroud)
它返回一个IntPtr作为结构成员的偏移量.这很有道理!并且您无法使用新Add方法轻松使用此偏移量.你必须把它投射到Int64,然后Add循环调用几次.
此外,它似乎杀死了IntPtr.Size与正确编写的应用程序无关的想法.您必须将偏移量转换为特定类型,例如Int64,此时您必须开始管理大小差异.并且想象出128位IntPtr出现时会发生什么.
我的问题是,为什么?
我的结论是否正确,还是我忽略了这一点?
它对应于x64架构中的限制.相对寻址仅限于带符号的32位偏移值.Matt Pietrek在这篇文章中提到了这一点(附近"幸运的是,答案是否定的").此限制还解释了为什么.NET对象在64位模式下仍限制为2GB.同样,在本机x64 C/C++代码中,内存分配也受到限制.这并不是说这是不可能的,排量可以存储在一个64位寄存器,它只是这将使数组索引一个很多更昂贵.
Marshal.OffsetOf()的神秘返回类型可能是一个角落案例.应用[StructLayout]和[MarshalAs]大于2GB后,托管结构可能会导致非托管版本.
是的,这不能很好地映射到未来的128位架构.但是当没有人知道它的外观时,准备今天的软件是非常困难的.也许古老的谚语很合适,对于任何人来说,16太字节应该足够了.除此之外还有很多空间可以增长,2 ^ 64相当大.当前的64位处理器仅实现2 ^ 48.在机器可以移动之前,需要解决一些严重的非平凡问题.