简体   繁体   中英

Pointer Arithmetic & Signed / Unsigned Conversions!

Incase of pointer arithmetic, are the integers automatically converted to their signed variants? If yes, why?

Suppose I do

int *pointer; 
int *pointerdiff;
unsigned int uiVal = -1;

pointerdiff = pointer + uiVal // Pointer will contain valid address here.

where pointer is a pointer to int and uiVal is initialized to -1, then I find that the address in pointers get decremented by 4. Why is the unsigned value of -1 not considered here?

It looks like your pointer is overflowing.

Let's do some maths. Say you're on a 32-bit machine, and your pointer is initialised to 0x 12 34 56 78 . We then initialise an unsigned int variable to -1 , which is 0x FF FF FF FF . Because it's an unsigned integer, the -1 is overflowing and actually represents 4 294 967 295 .

Your pointer is to an integer ( int* ), so each increment actually increments the address by sizeof int , which is 4 on a standard x86 machine. So we're actually adding 0x 03 FF FF FF FC (which is 0x FF FF FF FF * 4 ).

Now let's add the two together.

  0x 00 12 34 56 78
+ 0x 03 FF FF FF FC
-------------------
  0x 04 12 34 56 74

Of course, this overflows, because we now have a 40-bit value, and a pointer is 32 bits and can only hold that much information. We therefore lose the 04 at the start. This results in 0x 12 34 56 74 , which is 0x 12 34 56 78 - 4 .

Yes, integer operands are promoted. But that doesn't matter here. uiVal cannot be -1 if it's of unsigned type. Probably you did

unsigned int uiVal = -1;
pointer + uiVal ...

But that will do the same as

pointer + UINT_MAX ...

And this is likely to cause undefined behavior if the address range the pointer can hold can't cope with this addition. The Standard says at 5.7/4

For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, [...]. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise , the behavior is undefined.

That is, if the result pointer does not lie in the same array or one past the end, or if it does but did so by overflow, behavior is undefined.

我认为右操作数被转换为ptrdiff_t类型,这似乎是签名的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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