考虑以下 C 代码片段:
现在,在C语言中,预测会发生无符号溢出。我对x86_64汇编不太了解,但据我所见,16位参数寄存器被移动到32位寄存器中,并进行递增并返回。我的问题是,如果x == UINT16_MAX,则会发生溢出,标准规定x + 1 == 0,对吗?然而,由于%eax是一个32位寄存器,它现在包含UINT16_MAX + 1,这是不正确的。
这让我想到一个问题:是否有一种便携式的方法来禁用C中的无符号溢出,以便编译器可以假设存储在大型寄存器中的小变量的上位比特始终为0(因此它们不需要清除)?如果没有(或者解决方案在语法上很糟糕),那么至少在GCC中有没有办法实现呢?
非常感谢您的时间。
#include <stdint.h>
uint32_t inc(uint16_t x) {
return x+1;
}
当在纯x86_64系统上使用gcc-4.4.3编译并使用标志-std=c99 -march=core2 -msse4.1 -O2 -pipe -Wall时,它会产生以下结果:
movzwl %di,%eax
inc %eax
retq
现在,在C语言中,预测会发生无符号溢出。我对x86_64汇编不太了解,但据我所见,16位参数寄存器被移动到32位寄存器中,并进行递增并返回。我的问题是,如果x == UINT16_MAX,则会发生溢出,标准规定x + 1 == 0,对吗?然而,由于%eax是一个32位寄存器,它现在包含UINT16_MAX + 1,这是不正确的。
这让我想到一个问题:是否有一种便携式的方法来禁用C中的无符号溢出,以便编译器可以假设存储在大型寄存器中的小变量的上位比特始终为0(因此它们不需要清除)?如果没有(或者解决方案在语法上很糟糕),那么至少在GCC中有没有办法实现呢?
非常感谢您的时间。
unsigned int
吗? - Jens Gustedtuint16_t
的范围适合于int
,因此它将被提升为int
。对于unsigned char
也是一样。 - R.. GitHub STOP HELPING ICEint
类型更小的算术运算。任何算术表达式的结果都具有int
类型或更大类型。如果int
类型的转换级别高于uint16_t
类型,则两个uint16_t
变量的和具有int
类型;如果int
类型的转换级别低于uint16_t
类型,则它们的和具有uint16_t
类型。具体情况取决于您的实现中uint16_t
类型的级别,但是有规则将类型范围的相对大小与其级别相关联。 - R.. GitHub STOP HELPING ICE