Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usage of ptrdiff_t

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 and j-th elements of an array object, the expression (P)-(Q) has the value i−j provided the value fits in an object of type ptrdiff_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?

like image 652
Some Name Avatar asked Mar 26 '19 15:03

Some Name


People also ask

Why is Ptrdiff_t signed?

ptrdiff_t type is a base signed integer type of C/C++ language. The type's size is chosen so that it can store the maximum size of a theoretically possible array of any type.

What is Uintptr_t?

uintptr_t is an unsigned integer type that is capable of storing a data pointer (whether it can hold a function pointer is unspecified). Which typically means that it's the same size as a pointer. It is optionally defined in C++11 and later standards.

What is pointer arithmetic in C plus plus?

Pointer arithmetic. The C++ language allows you to perform integer addition or subtraction operations on pointers. If ptr points to an integer, ptr + 1 is the address of the next integer in memory after ptr. ptr - 1 is the address of the previous integer before ptr .

Is Size_t always the size of a pointer?

The size of size_t and ptrdiff_t always coincide with the pointer's size. Because of this, it is these types that should be used as indexes for large arrays, for storage of pointers and pointer arithmetic.


1 Answers

From the specification (section 7.20.3)

Its implementation-defined value shall be equal to or greater in magnitude (absolute value) than the corresponding value given below

[Emphasis mine]

So the values mentioned are only minimum values. The implementation could have larger limits. I would expect ptrdiff_t to be the word-length of the target platform (i.e. a 64-bit type of 64-bit systems).

And note that size_t is an unsigned integer type, while ptrdiff_t is a signed integer type. That kind of implies that not all values of a size_t could be represented by a ptrdiff_t.

like image 172
Some programmer dude Avatar answered Oct 08 '22 19:10

Some programmer dude