【发布时间】:2015-04-07 06:15:21
【问题描述】:
我目前的 a problem 带有不安全的指针,这似乎是一个编译器错误。
注意:问题不在于我使用了指针和不安全的代码;该代码运行良好。该问题与已确认的编译器错误有关,该错误在某些情况下拒绝编译合法代码。如果您对此问题感兴趣,请访问my other question
由于我的问题在于指针变量的声明,我决定解决这个问题,改用IntPtr,并在需要时转换为实际指针。
但是,我注意到我不能这样做:
IntPtr a = something;
IntPtr b = somethingElse;
if (a > b) // ERROR. Can't do this
{
}
> 和 < 运算符似乎没有为 IntPtr 定义。请注意,我确实可以比较两个实际的指针。
IntPtr 有一个.ToInt64() 方法。但是,这会返回一个 有符号 值,当涉及正值和负值时,与 > 和 < 进行比较时,可能会返回不正确的值。
说实话,考虑到pointer comparisons are performed unsigned,我真的不明白返回有符号值的.ToInt64() 方法有什么用,但这不是我的问题。
有人可能会说IntPtrs 是不透明的句柄,因此与> 和< 进行比较是没有意义的。不过我要指出的是IntPtr有加减法,也就是说IntPtr其实有一个顺序的概念,所以>和<确实有意义。
我想我可以将ToInt64() 的结果转换为ulong 然后进行比较,或者将IntPtr 转换为指针然后进行比较,但这让我想为什么不是>以及为IntPtr 定义的<。
为什么我不能直接比较两个IntPtrs?
【问题讨论】:
-
注意
IntPtr是有符号的,所以最后它相当于一个int或一个long。如果您希望它未签名,请使用UIntPtr -
@xanatos:我不太确定。我认为
IntPtr是一个内部带有void*的结构。我可以完美地比较void*,所以我认为实际的不安全指针在 CLR 内部是无符号的。不幸的是,大多数与内存相关的函数,例如Marshal.AllocHGlobal()返回IntPtr而不是UIntPtr。让我想知道为什么有两种不同的类型,一个指针一个指针一个指针。 -
在我的回答中添加了另一部分关于签名 IntPtr 的原因
-
@PandaPajama:“我可以完美地比较 void”* - 也许,有点。如果它们指向同一个对象或指向同一个数组中或后一个数组的元素,那么这样的比较就可以了。否则,比较会导致未定义的行为。
-
@EdS:是这样吗?
AllocHGlobal既不返回对象也不返回数组,但我可以在我得到的地址空间内有意义地进行指针比较。