繁体   English   中英

指针算术和签名/无符号转换!

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM