6

这是一个看起来很简单的问题:

鉴于原生大小的整数最适合算术,为什么 C#(或任何其他 .NET 语言)不支持原生大小的算术IntPtrUIntPtr

理想情况下,您可以编写如下代码:

for (IntPtr i = 1; i < arr.Length; i += 2) //arr.Length should also return IntPtr
{
    arr[i - 1] += arr[i]; //something random like this
}

这样它就可以在 32 位和 64 位平台上运行。(目前,您必须使用long.)


编辑:

没有将它们用作指针(甚至没有提到“指针”这个词)!它们可以被视为native intMSIL 和intptr_tC中的 C# 对应物stdint.h——它们是整数,而不是指针。

4

5 回答 5

6

在 .NET 4 中,支持类型IntPtr的左手操作数和整数类型的右手操作数(intlong等)之间的算术运算。

[编辑]:正如其他人所说,它们旨在表示本地语言中的指针(正如名称 IntPtr 所暗示的那样)。可以声称您将它们用作本机整数而不是指针,但您不能忽视整数的本机大小一直很重要的主要原因之一是用作指针。int如果您正在执行数学运算或其他独立于您的代码运行的处理器和内存架构的通用功能,则可以说使用类型更有用和更直观,例如long您知道它们的固定大小和上限无论硬件如何,每种情况下的下限。

正如该类型IntPtr旨在表示本机指针一样,算术运算旨在表示您将对指针执行的逻辑数学运算:将一些整数偏移量添加到本机指针以到达新的本机指针(而不是添加两个IntPtrs不支持,也不IntPtr用作右手操作数)。

于 2011-04-08T02:55:22.000 回答
6

也许本机大小的整数可以实现最快的算术运算,但它们肯定不适合最无错误的程序。

就我个人而言,我讨厌使用整数类型进行编程,当我坐下来开始输入时,我不知道它们的大小(我在看着你,C++),而且我绝对更喜欢 CLR 类型给你带来的安心,而不是非常怀疑和肯定的使用为平台量身定制的 CPU 指令可能会提供有条件的性能优势。

还要考虑 JIT 编译器可以针对运行进程的体系结构进行优化,而“常规”编译器必须生成机器代码而无法访问此信息。因此,JIT 编译器可能会以同样快的速度生成代码,因为它知道的更多。

我想我并不是唯一一个这样想的人,所以这可能是有原因的。

于 2011-04-08T03:03:20.073 回答
1

我实际上可以想到 IntPtr(或 UIntPtr)有用的一个原因:访问数组的元素需要原生大小的整数。尽管原生整数从未暴露给程序员,但它们在 IL 内部使用。像some_array[index]C# 中的东西实际上会some_array[(int)checked((IntPtr)index)]在 IL 中编译。在用 ILSpy反汇编我自己的代码后,我注意到了这一点。(index我的代码中的变量是 64 位的。)为了验证反汇编程序没有出错,微软自己的 ILDASM 工具显示了conv.uconv.i我的程序集中的说明​​。这些指令将整数转换为系统的本机表示。我不知道在 IL 代码中包含所有这些转换指令对性能的影响是什么,但希望 JIT 足够聪明,可以优化性能损失;如果不是,那么下一个最好的事情是允许在不进行转换的情况下操作本机整数(在我看来,这可能是使用本机类型的主要动机)。

目前,F# 语言允许使用nativeintand 及其无符号对应物进行算术运算。但是,数组只能int在 F# 中被索引,这意味着nativeint对于索引数组的目的不是很有用。

如果它真的让你很困扰,那就编写你自己的编译器来解除对本地整数使用的限制,创建你自己的语言,在 IL 中编写你的代码,或者在编译后调整 IL。就个人而言,我认为通过使用本机 int 来挤出额外的性能或节省内存是一个坏主意。如果您希望您的代码像手套一样适合系统,您最好使用支持处理器内在函数的较低级别的语言。

于 2012-05-27T07:08:37.067 回答
0

.Net Framework 尽量不引入无法解释的操作。即没有 DateTime + DateTime 因为没有像 2 个日期之和这样的概念。相同的推理适用于指针类型 - 没有 2 个指针之和的概念。IntPtr 被存储为平台相关的 int 值这一事实并不重要——还有很多其他类型在内部存储为基本值(再次,DateTime 可以表示为 long)。

于 2011-04-08T04:16:50.473 回答
-1

因为这不是处理内存寻址的“安全”方式。指针算法可能导致 C# 明确设计要避免的各种错误和内存寻址问题。

于 2011-04-08T02:50:05.397 回答