Richard said:
Even if it wasnt initialised it would be incremented by something.
If x isn't initialized, referring to its value invokes undefined
behavior. It's likely, but by no means certain, that the behavior
would be *as if* it were incremented. It's also possible, on some
systems, that x could have a value such that attempting to read it
causes a program crash. (Before you ask, no, I don't have an
example.)
Proof of nothing. You are, again, being purposely difficult.
The ++ operator increments its operand by 1, by definition. The
question is, 1 what? In the case of:
long int *x = some_value;
x ++;
it advances it by 1 long int object, i.e., causes it to point to the
next adjacent long int object in memory, assuming that such an object
exists; it can also legally point just past the end of an array.
long int i[1], *p = i, *q = &i[1];
Note that evaluating &i[1] is ok, and equivalent to i+1, but only
because of a special-case rule; see C99 6.5.3.2p3.
Yes, because of the way pointer subtraction is defined.
And the following:
int main() {
long int i[1], *p = i, *q = &i[1];
printf("%u\n",p++);
printf("%u\n",p++);
printf("%u\n", (int)(p - q));
}
The first printf gives me:
3214862936
And the second:
3214862940
Now, that is 4. On my machine.
You're using "%u" to print pointer values. Surely you know that
invokes undefined behavior, and I know of common real-world systems
where it won't work (e.g., where int is 32 bits and pointers are 64
bits). You're also using "%u" to print an int value; if you had
written
printf("%u\n", (unsigned)(p - q));
that wouldn't be no problem. (Actually printing a non-negative int
value using %u is probably ok, due to another special-case rule, but
there's no point in taking advantage of that fact.) Finally, p starts
as a pointer to the first and only element of a 1-element array. You
increment it twice, causing it to point *past* the end of the array.
Yet another instance of undefined behavior that happens to "work" on
your system -- and it wasn't even necessary to demonstrate your point.
You're making unwarranted (though commonly valid) assumptions about
pointer representations and conversions. This program:
#include <stdio.h>
int main(void)
{
long array[10];
long *p = &array[0];
long *q = &array[1];
printf("%d %d %d\n",
(int)sizeof(long), (int)(q - p), (int)q - (int)p);
return 0;
}
will typically print "4 1 4" on a system where sizeof(long)==4. I've
worked on a real-world system where it would print "8 1 1" due to a
rather unusual pointer representation.
And the thing is, all this undefined behavior wasn't even necessary to
demonstrate your point. Here's a portable program (with
implementation-defined but not undefined behavior) that illustrates
what you're trying to talk about:
#include <stdio.h>
#include <assert.h>
int main(void)
{
long array[10];
long *p = &array[0];
long *q = &array[1];
int diff = q - p;
int byte_diff = (char*)q - (char*)p;
printf("p = %p\n", (void*)p);
printf("q = %p\n", (void*)q);
printf("sizeof(long) = %d\n", (int)sizeof(long));
printf("diff = %d\n", diff);
printf("byte_diff = %d\n", byte_diff);
assert(diff == 1);
assert(byte_diff == sizeof(long));
return 0;
}
On my system, I get:
p = 0xbfce19ac
q = 0xbfce19b0
sizeof(long) = 4
diff = 1
byte_diff = 4
And here's the point:
p++ increments p by 1. If p is a long*, this means that it advances
the memory location to which it points by 1 long, or by sizeof(long)
bytes.