struct Item {
int i;
char * x;
};
Item all[] = { {0, "0"}, {1, "1"}, {2, "2"}, };
int i = all - (Item *) &all[2].x ;
printf("i = %d\n", i);
in the above code, I cast &all[2].x to (Item*) and perform a pointer substract operation,
mingw g++(4.6.1) produces -2, and VC2010 produces -3.
Is such operation a well-defined behavior (then VC likely has a bug, anyway the distance between the two pointer is 2 elements) or not?
I’ve search the ANSI C standard(C99) 6.5.6 Semantics(9) says:
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.
It’s not very clear(what ‘shall’ imply) whether pointing to data member of the object is also ok.
I’ve also checked with <> Section 7.6.2 Additive operatives/Substraction, which says:
… The result is well defined and portable only if
the two pointers point to objects in the same array or point to one past the last object of the
array.
Looks like the pointer must point to the object itself, point to data member of the object is not well-defined. But the statement does not declare it explicitly.
There’s another resource which says:
( p2 - p1 ) == ( addr( p2 ) - addr( p1 ) ) / sizeof( T )…
p2andp1need not point to valid elements in an array. The formula above still works even whenp2andp1contain invalid addresses (because they contain some address).
Which confuse me further.
Anyone please clarify this subtle issue?
The part you have quoted from the standard is clear:
&all[2].xdoes not point to an element of the arrayall. Pointing at a subobject of an element is not pointing at an element.This means that the behaviour is undefined.