Reputation: 19864
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
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
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
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
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
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
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