I'm implementing iterator through continuous chunk of memory and came to the issue about its conforming usage. My current implementation (assuming I'm iterating through array of chars).
typedef struct iterator{ void *next_ptr; void *limit; //one past last element pointer } iterator_t; void *next(iterator_t *iterator_ptr){ void *limit = iterator_ptr -> limit; void *next_ptr = iterator_ptr -> next_ptr; ptrdiff_t diff = limit - next_ptr; if(diff <= 0){ return NULL; } iterator_ptr -> next_ptr = ((char *) next_ptr) + 1; return next_ptr; } The issue is the Standard claims at 6.5.6(p9) that:
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
This is true. I assume the area I'm iterating through is an array.
If the result is not representable in an object of that type, the behavior is undefined. In other words, if the expressions point to, respectively, the
i-th andj-th elements of an array object, the expression(P)-(Q)has the valuei−jprovided the value fits in an object of typeptrdiff_t.
The limits of ptrdiff_t are defined at 7.20.3(p2):
limits of
ptrdiff_t
PTRDIFF_MIN−65535
PTRDIFF_MAX+65535
There is no any guarantees that all values represented with size_t should be represented with ptrdiff_t.
So we judging by the limits we can conformingly subtract pointers of an array only of 65535 elements at most? So this would not work in general case where I want to subtract two pointers to elements of an array of unknown size?
PTRDIFF_MIN −65535andPTRDIFF_MAX +65535? These limits are platform dependent, but 65535 seems tiny to me.SIZE_MAXshould agree withPTRDIFF_MIN/MAXon the specific implementation to make sense.intptr_tThat won't work. You have to convert touintptr_tor the resulting difference can be incorrect. Then you run into the same problem of not having enough bits to represent the same magnitude along with a direction for the difference.void*undefined? You can't have an array ofvoidobjects.