将int32加到64位本机int的结果是什么?

13

当将一个int32加到一个64位的native int时,CLR是进行符号扩展还是零扩展32位整数?最重要的是:它基于什么信息做出这个选择?


我正在编写一个.NET编译器,并已经彻底阅读了ECMA规范,但找不到答案。

  

CLI仅支持在其操作中对其评估堆栈上存储的值的子集执行此类操作:int32int64native int。   
-- ECMA 335,第I12.1节:支持的数据类型

由于评估堆栈上的值没有有关其有符号性的信息,因此涉及操作数的符号的指令有两个变体:一个用于有符号整数,一个用于无符号整数。addsubmul指令(那些不检查溢出的指令)只要操作数大小相同就不需要关心操作数的符号,因此只有一个变体。 然而,操作数并不总是相同的大小...

ECMA 335,第III1.5节:操作数类型表指出可以将int32native int相加、相减、相乘和相除。结果再次是一个native int。在64位系统上,native int宽度为64位。

ldc.i4.0            // Load int32 0
conv.i              // Convert to (64-bit) native int
ldc.i4.m1           // Load int32 -1
add                 // Add native int 0 and int32 0xFFFFFFFF together

那么这里会得到什么结果?需要注意的是,根据规范,运行时不需要跟踪堆栈上值的确切类型或带符号性:它只知道 int32int64native int(以及其他些许与本处无关的类型)。


我想象 IntPtrUIntPtr 的算术运算,由于它们在内部表示为 native ints,也会使用这种类型的加法。然而,ILSpy 显示在 C# 中将 IntPtrInt32 相加调用了 IntPtr 类的重载 + 操作符,该操作符仅接受带符号的 Int32 参数。

使用 CIL 直接执行它(使用 add 指令)还表明整数被解释为带符号数。它也应该已经在 Mono 中实现了,但我找不到任何参考来支持我的发现。


提升值的符号不会被捕获。请参考此信息以获取可能的解决方案(这是针对Mac的,但在这种情况下并不重要):https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/64bitPorting/MakingCode64-BitClean/MakingCode64-BitClean.html - user1693593
2个回答

5
当两个相同位数的值相加时,符号不重要。例如,将32位的-10 (0xfffffff6) 和 32位的10 (0x0000000a) 相加会得到正确的结果0。因此,在CIL(通用指令语言)中只有一个add指令。
然而,当两个不同位数的值相加时,符号是很重要的。例如,将32位的-10和64位的10相加,如果无符号相加,则结果可能为4294967296 (0x100000000);但如果有符号相加,则结果为0。
CIL的add指令允许将本机整数32位整数相加。本机整数可以是64位(在64位系统上)。 测试表明,add将32位整数视为有符号整数,并进行符号扩展。这并不总是正确的,可能被认为是一个错误。Microsoft目前不打算修复它。
由于溢出检查取决于操作数是被视为无符号还是有符号,因此有两个变体的add.ovfadd.ovf(有符号)和add.ovf.un(无符号)。但是,当将32位整数添加到本机整数时,这些变体也会正确地进行符号扩展或零扩展较小的操作数。
因此,将本机整数和无符号32位整数相加可能会产生不同的结果,具体取决于C#的溢出检查设置。显然,我无法弄清楚这一点是CIL语言设计中的一个错误或疏忽导致的。

2
您现在处于未知领域,我不知道是否有任何.NET语言实际允许这样做。他们的语法检查器会拒绝任何试图执行此操作的代码。即使是添加两个本机整数也被拒绝。最终由Jitter为其生成机器代码。如果您想知道发生了什么,请进行实验。请务必测试至少x86和x64 Jitter。
考虑到含糊不清的语义以及未来Jitter更改可能会破坏您的假设,我强烈建议您在自己的语言中也拒绝此操作。它并不是非常有用,一个简单的解决方法是将其转换为(long)并将结果返回到(IntPtr),具有良好定义的语义。这本身就是在自己的代码生成器中获得可预测行为的一种方式。

我在帖子中添加了一些信息:当将IntPtr加上Int32时,C#使用重载的加法运算符。在CIL中,add指令似乎将Int32解释为有符号数。但是,我不知道为什么会这样。 - Daniel A.A. Pelsmaeker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接