What is the correct type for array indexes in C?

I think you should use ptrdiff_t for the following reasons

  • Indices can be negative. Therefore for a general statement, all unsigned types, including size_t, are unsuitable.
  • The type of p2 - p1 is ptrdiff_t. If i == p2 - p1, then you should be able to get p2 back by p2 == p1 + i. Notice that *(p + i) is equivalent to p[i].
  • As another indication for this “general index type”, the type of the index that’s used by overload resolution when the builtin operator[] (for example, on a pointer) competes against a user-provided operator[] (for example vector’s) is exactly that (http://eel.is/c++draft/over.built#16):
    >

    For every cv-qualified or cv-unqualified object type T there exist candidate operator functions of the form

    T*      operator+(T*, std::ptrdiff_t);
    T&      operator[](T*, std::ptrdiff_t);
    T*      operator-(T*, std::ptrdiff_t);
    T*      operator+(std::ptrdiff_t, T*);
    T&      operator[](std::ptrdiff_t, T*);
    

EDIT: If you have a really big array or a pointer to a really big memory portion, then my “general index type” doesn’t cut it, as it then isn’t guaranteed that you can subtract the first element’s address from the last element’s address. @Ciro’s answer should be used then https://stackoverflow.com/a/31090426/34509 . Personally I try to avoid using unsigned types for their non-ability to represent negative edge cases (loop end-values when iterating backwards for example), but this is a kind of religious debate (I’m not alone in that camp, though). In cases where using an unsigned type is required, I must put my religion aside, of course.

Leave a Comment