Gopi
Gopi

Reputation: 19864

Pointer difference between 2 int pointers

int main(void) {
    int *a;
    int *b = a++;
    printf("%d\n",b-a);
    return 0;
}

I expected the output to be 1 why is it -1?

Assume in the above question instead of a++ I have ++a.

Is it still undefined behavior?

Upvotes: 0

Views: 1222

Answers (6)

ytobi
ytobi

Reputation: 673

That is no undefine behaviour

when you declared *a, a points to a memory location, *b = a++; b to point to the same location as a, AND increaments a to point to a location 1 factor greater than the previous location that b points to.

b - a = -1 //correct

i'll give example

int main(void)
     {
        int *a; // 0x408
        int *w = a++; // 0x400
        int *b = a++; // 0x404

        int c = (b-a);
        printf("%d\n",b-a);// -1
        printf("%d\n",w-a); // -2

        return 0;
    }

i intruduce w to better ilustrate

The run-time memory address of the variable will look similar to the ones above.

b - a ( 0x404 - 0x408) == -1( -4 );

the sizeof int( in this case ) is 4 bytes. and pointers holding the address of int will have their address changing(+/-) by factor of 4, as far is int is concern in this case 4 bytes hold one integer(1 unit)

w - a == (0x400 - 0x408) = -2( -8 )

if you had

a - w == (0x408 - 0x400) = 2( 8 )

Upvotes: -1

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

The First problem, as I see here, is primarily with

 int *a;

a is automatic local, and the initial value is indeterminate (no explicit initialization), hence doing a++ (or, ++a, for the matter) invokes undefined behavior.

That said, regarding the pointer subtraction, see this answer on why we need the operands of subtraction operator to be address of elements from same array object.

Finally, the subtraction of two pointers produce the type ptrdiff_t, you should be using %td to print the result. Otherwise, you again invoke UB.


[As mentioned in below comments]

Assuming the pointers are initialized properly, something like

int k[5] = {0};
int * a = &(k[0]);
int *b = a++;
printf("%td\n",b-a);

in that case, the result will be -1, as that is the difference in the index of both the elements (remember a++ is post-increment).

Chapter §6.5.6/9, C11 standard

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

Upvotes: 4

Akash Mahapatra
Akash Mahapatra

Reputation: 3238

Difference of two pointers ((b-a) in this case) is not defined in C unless the two pointers are pointing to addresses of a same array.

Also, since the pointer 'a' in your code has not been assigned any address ( contains garbage value ), doing any kind of operation is a sin.

If you wish to see how does subtraction of two pointers work, then try to define an array and make these two pointers point to it.

Upvotes: 3

2501
2501

Reputation: 25752

First of all, your code causes undefined behavior because it reads and modifies uninitialized variables.

Also the specifier %td should be used for printing pointer difference.

Let's assume the pointer a actually points to a valid object:

int i;
int *a = &i;
int *b = a++;
printf("%td\n",b-a);

The postfix ++ operator gives the current value of the operand and then increments the operand by one. The above code is identical to:

int i;
int *a = &i+1;
int *b = &i;
printf("%td\n",b-a);

Pointer a points to one-past the object i, and pointer b points to the object i. The subtraction will, due to pointer arithmetic, yield -1. If the operation was: a-b then the result would be 1.

This is defined behavior.

Upvotes: 4

Lundin
Lundin

Reputation: 213418

int *a is a variable with automatic storage duration and never has its address taken (&a). The code therefore invokes undefined behavior (as per 6.3.2.1, see this) and your program can't have any predictable outcome.

Using the %d format specifier on on a ptrdiff_t also invokes undefined behavior (7.21.6.1/9). You should use %td for ptrdiff_t and %p for pointers.

Thus you can't expect anything from your program. It can output anything, or nothing, or crash.

Upvotes: 0

tigris_kn
tigris_kn

Reputation: 1

When you increment the pointer, it does not add the value to 1. It just tells the pointer to point to the next location. Also, your pointers were never initialized and they are just pointing to random garbage numbers.

Upvotes: 0

Related Questions