新的 IntPtr.Add 方法 - 我是否错过了 int 的要点?

发布于 2024-10-04 17:21:55 字数 1327 浏览 0 评论 0原文

从 FW 4.0 开始,IntPtr 结构< /a> 具有 添加< /a> 方法:

public static IntPtr Add(
    IntPtr pointer,
    int offset
)

这很棒,因为它应该解决我们遇到的关于 IntPtr 数学的所有问题 (12,可能更多)。

但为什么offsetint
一定不是IntPtr吗?我可以轻松想象将 64 位指针偏移超出 int 范围的值。


例如,考虑 Marshal.OffsetOf

public static IntPtr OffsetOf(
    Type t,
    string fieldName
)

它返回一个IntPtr作为结构成员的偏移量。这很有道理!并且您无法通过新的 Add 方法轻松使用此偏移量。您必须将其转换为 Int64,然后在循环中多次调用 Add

此外,它似乎消除了 IntPtr.Size 与正确编写的应用程序无关的想法。您必须将偏移量转换为特定类型,例如 Int64,此时您必须开始管理大小差异。想象一下当 128 位 IntPtr 出现时会发生什么。


我的问题是,为什么?
我的结论是正确的,还是我没有抓住要点?

Starting from FW 4.0, the IntPtr structure has the Add method:

public static IntPtr Add(
    IntPtr pointer,
    int offset
)

Which is great, as it's supposed to address all those questions on IntPtr math we have had (1, 2, probably more).

But why is the offset int?
Must it not be IntPtr? I can easily imagine offsetting a 64-bit pointer by a value which is beyond the int range.


For instance, consider Marshal.OffsetOf:

public static IntPtr OffsetOf(
    Type t,
    string fieldName
)

It returns an IntPtr as the offset to the structure member. Which makes perfect sense! And you cannot easily use this offset with the new Add method. You'd have to cast it to Int64, then call Add several times in a loop.

Also, it seems to kill the very idea of the IntPtr.Size being irrelevant to a properly written application. You will have to cast the offset to a particular type, such as Int64, at which point you must start managing the size difference. And image what will happen when 128-bit IntPtr appears.


My question here is, why?
Am I correct in my conclusions, or am I missing the point?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

装纯掩盖桑 2024-10-11 17:21:55

它对应于 x64 架构中的限制。相对寻址仅限于带符号的 32 位偏移值。 Matt Pietrek 在这篇文章中提到了这一点(靠近“幸运的是,答案是否定的”)。此限制也解释了为什么 .NET 对象在 64 位模式下仍限制为 2GB。同样,在本机 x64 C/C++ 代码中,内存分配也受到限制。并不是说不可能,位移可以存储在 64 位寄存器中,只是这会使数组索引变得更加昂贵。

Marshal.OffsetOf() 神秘的返回类型可能是一个极端情况。应用大于 2GB 的 [StructLayout] 和 [MarshalAs] 后,托管结构可能会产生非托管版本。

是的,这不能很好地映射到未来的某些 128 位架构。但是,当没有人知道它会是什么样子时,为当今的拱门准备软件是非常困难的。也许古老的格言很合适,16 TB 对任何人来说都应该足够了。除此之外,还有很多的增长空间,2^64 是一个相当大的数字。当前的 64 位处理器仅实现 2^48。在机器能够如此接近之前,需要解决一些非常重要的问题。

It corresponds to a restriction in the x64 architecture. Relative addressing is limited to a signed 32-bit offset value. Matt Pietrek mentions this in this article (near "Luckily, the answer is no"). This restriction also explains why .NET objects are still limited to 2GB in 64-bit mode. Similarly, in native x64 C/C++ code memory allocations are limited as well. It is not that it is impossible, the displacement could be stored in a 64-bit register, it is just that this would make array indexing a lot more expensive.

The mysterious return type of Marshal.OffsetOf() is probably a corner-case. A managed struct could result in an unmanaged version after applying [StructLayout] and [MarshalAs] that's larger than 2GB.

Yes, this wouldn't map well to some future 128-bit architecture. But it is extraordinarily difficult to prep today's software for an arch when nobody knows what it will look like. Perhaps the old adage fits, 16 Terabytes ought to be enough for anybody. And there's lots of room left to grow beyond that, 2^64 is rather a large number. Current 64-bit processors only implement 2^48. Some seriously non-trivial problems need to be solved before machines can move that close.

日久见人心 2024-10-11 17:21:55

如果您仅定义:

public static IntPtr Add(IntPtr pointer, IntPtr offset)

那么,向 64 位指针添加 32 位偏移量的可读性较差,恕我直言。

同样,如果您定义

public static IntPtr Add(IntPtr pointer, long offset)

then,则向 32 位指针添加 64 位偏移量也是不好的。

顺便说一句,Substract 返回一个 IntPtr,因此 IntPtr 逻辑无论如何都不会被破坏。

If you define only:

public static IntPtr Add(IntPtr pointer, IntPtr offset)

then, adding a 32 bits offset to a 64 bits pointer is less readable, IMHO.

Again, if you define

public static IntPtr Add(IntPtr pointer, long offset)

then, adding a 64 bits offset to a 32 bits pointer is also bad.

By the way, Substract returns an IntPtr, so the IntPtr logic is not broken in anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文