[英]Pointer Arithmetic & Signed / Unsigned Conversions!
包含指针算术,是否会自动转换为有符号变量的整数? 如果是,为什么?
假设我这样做
int *pointer;
int *pointerdiff;
unsigned int uiVal = -1;
pointerdiff = pointer + uiVal // Pointer will contain valid address here.
其中指针是指向int的指针,uiVal初始化为-1,然后我发现指针中的地址减少了4.为什么这里没有考虑无符号值-1?
看起来你的指针溢出了。
我们来做一些数学。 假设您使用的是32位计算机,并且指针初始化为0x 12 34 56 78
。 然后我们将unsigned int变量初始化为-1
,即0x FF FF FF FF
。 因为它是无符号整数,所以-1
溢出,实际上代表4 294 967 295
。
你的指针是一个整数( int*
),所以每个增量实际上都是通过sizeof int
递增地址,在标准的x86机器上是4。 所以我们实际上添加了0x 03 FF FF FF FC
(这是0x FF FF FF FF * 4
)。
现在让我们将两者加在一起。
0x 00 12 34 56 78
+ 0x 03 FF FF FF FC
-------------------
0x 04 12 34 56 74
当然,这会溢出,因为我们现在有一个40位的值,一个指针是32位,只能容纳那么多信息。 因此我们在开始时失去04
。 这导致0x 12 34 56 74
,其为0x 12 34 56 78 - 4
。
是的,整数操作数被提升。 但这并不重要。 如果它是无符号类型,则uiVal
不能为-1
。 可能你做到了
unsigned int uiVal = -1;
pointer + uiVal ...
但那样做也会如此
pointer + UINT_MAX ...
如果指针可以容纳的地址范围无法应对此添加,则可能会导致未定义的行为。 该标准以5.7/4
出于这些运算符的目的,指向非阵列对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型。
当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型。 如果指针操作数指向数组对象的元素,并且数组足够大,[...]。 如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则 ,行为未定义。
也就是说,如果结果指针不在同一个数组中或者在结尾之后,或者如果它通过溢出而这样做,则行为是未定义的。
我认为右操作数被转换为ptrdiff_t类型,这似乎是签名的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.