C# 为什么可以';比较两个IntPtr';带<;以及>;?
我目前正在使用不安全的指针,这似乎是一个编译器错误 注意:问题不在于我使用的是指针和不安全代码;代码运行得很好。该问题与一个已确认的编译器bug有关,该bug在某些情况下拒绝编译合法代码。如果您对该问题感兴趣,请访问 因为我的问题是指针变量的声明,所以我决定解决这个问题,改为使用C# 为什么可以';比较两个IntPtr';带<;以及>;?,c#,pointers,C#,Pointers,我目前正在使用不安全的指针,这似乎是一个编译器错误 注意:问题不在于我使用的是指针和不安全代码;代码运行得很好。该问题与一个已确认的编译器bug有关,该bug在某些情况下拒绝编译合法代码。如果您对该问题感兴趣,请访问 因为我的问题是指针变量的声明,所以我决定解决这个问题,改为使用IntPtr,并在需要时转换为实际指针 然而,我注意到我不能这样做: IntPtr a = something; IntPtr b = somethingElse; if (a > b) // ERROR. Can
IntPtr
,并在需要时转换为实际指针
然而,我注意到我不能这样做:
IntPtr a = something;
IntPtr b = somethingElse;
if (a > b) // ERROR. Can't do this
{
}
似乎没有为codeIntPtr/code定义
和我想我可以将codeToInt64()/code的结果转换为codeulong/code,然后进行比较,或者将codeIntPtr/code转换为指针,然后进行比较,但这让我想,为什么code>
和
一直被忽视了。在.NET 4.0之前,甚至没有IntPtr
/添加
和运算符+
/减法
现在。。。如果要比较两个指针,请将它们转换为运算符-
(如果它们是long
),或转换为IntPtr
(如果它们是ulong
)。请注意,在Windows上,只有在使用带有UIntPtr
选项的32位程序时,才需要/3GB
,因为否则32位程序只能使用较低的2gb地址空间,而对于64位程序,使用的地址空间远小于64位(此时) 显然,如果您在.NET中进行内核编程,则会发生以下变化:-)(我希望:-)我在这里参加比赛 鉴于UIntPtr
优于IntPtr
的原因: IntPtr类型符合CLS,而UIntPtr类型不符合CLS。公共语言运行库中仅使用IntPtr类型。提供UIntPtr类型主要是为了保持与IntPtr类型的架构对称性 有些语言不区分有符号类型和无符号类型。NET希望支持他们 使用UIntPtr
(我甚至可以使我的图形适配器崩溃:-) 注意,由于符号扩展的工作方式,您不能简单地执行editbin /LARGEADDRESSAWARE myprogram.exe
,因为在32位时它将中断(uintpttr)(ulong)(long)ptr
但请注意,很少有程序真正支持32位大于2GB的数据 IMHO,IntPtr并不是为高/低比较等目的而开发的。它是一种存储内存地址的结构,只能进行相等性测试。你不应该考虑任何事物在内存中的位置(这是CLI管理的)。这就像比较Enternet中哪个IP更高。比较IntPtr非常非常危险。C语言不允许这样做的核心原因,即使CLR对此没有问题 IntPtr经常用于存储非托管指针值。最大的问题是:指针值不是有符号的值。只有UIntPtr是存储它们的适当托管类型。UIntPtr的一个大问题是它不是一个符合CLS的类型。许多语言不支持无符号类型。Java、JScript和VB.NET的早期版本就是例子。因此,所有框架方法都使用IntPtr 它特别令人讨厌,因为它经常毫无问题地工作。从32位版本的Windows开始,地址空间的上限2GB保留给操作系统,因此程序中使用的所有指针值始终为0x8000000。现在IntPtr比较在完全随机的情况下失败了。例如,0x80000100的值实际上大于0x7FFFFFE00,但比较结果表明它更小。不好的。而且这种情况并不经常发生,指针值往往是相似的。它是非常随机的,实际的指针值是高度不可预测的 这是一个没有人能诊断的错误
使用C或C++的程序员也很容易犯这个错误,他们的语言并不能阻止他们。微软想出了另一种方法来避免这种痛苦,这种程序必须与特定的链接才能获得超过2GB的地址空间。请注意,是有符号的,因此最终它相当于IntPtr
或int
。如果您想让它不签名,请使用long
@xanatos:我不太确定。我认为UIntPtr
是一个内部带有IntPtr
的结构。我可以完美地比较void*
,因此我认为实际的不安全指针在CLR中没有签名。不幸的是,大多数与内存相关的函数,如void*
返回marshall.AllocHGlobal()
,而不是IntPtr
。我想知道为什么有两种不同的类型,一个指针就是一个指针就是一个指针IntPtr@PandaPajama:“我可以完美地比较空虚”*-也许,有点。如果它们指向同一个对象,或者指向同一数组中的元素,或者指向同一数组末尾的元素,则可以进行这样的比较。否则,比较UIntPtr
static void Main(string[] args) { Console.WriteLine("Is 64 bits", Environment.Is64BitProcess); const int memory = 128 * 1024; var lst = new List<IntPtr>(16384); // More than necessary while (true) { Console.Write("{0} ", lst.Count); IntPtr ptr = Marshal.AllocCoTaskMem(memory); //IntPtr ptr = Marshal.AllocHGlobal(memory); lst.Add(ptr); if ((long)ptr < 0) { Console.WriteLine("\nptr #{0} ({1}, {2}) is < 0", lst.Count, ptr, IntPtrToUintPtr(ptr)); } } }
public static UIntPtr IntPtrToUintPtr(IntPtr ptr) { if (IntPtr.Size == 4) { return unchecked((UIntPtr)(uint)(int)ptr); } return unchecked((UIntPtr)(ulong)(long)ptr); }