Я реализую итератор через непрерывный кусок памяти и пришел к вопросу о его соответствующем использовании. Моя текущая реализация (при условии, что я перебираю массив char
s).
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;
}
Проблема заключается в стандартных претензиях на 6.5.6(p9)
, которые:
Когда вычтены два указателя, оба должны указывать на элементы
тот же объект массива, или один за последним элементом массива
объект
Это правда. Я предполагаю, что область, через которую я итерирую, является массивом.
Если результат не может быть представлен в объекте этого
тип, поведение не определено. Другими словами, если
выражения указывают, соответственно, на i
-й и j
-й элементы
объект массива, выражение (P)-(Q)
имеет значение i−j
значение вписывается в объект типа ptrdiff_t
.
Пределы ptrdiff_t
определены в 7.20.3(p2)
:
пределы ptrdiff_t
PTRDIFF_MIN
−65535
PTRDIFF_MAX
+ 65535
Нет никаких гарантий, что все значения, представленные size_t
, должны быть представлены ptrdiff_t
.
То есть мы, судя по пределам, можем соответственно вычитать указатели массива максимум из 65535
элементов? Так что это не будет работать в общем случае, когда я хочу вычесть два указателя на элементы массива неизвестного размера?