For maximum portability what should the type of an array index be? Can
any integer type be used safely? Or should I only use an unsigned type?
Or what?
If I'm using pointers to access array elements as *(mptr+k) where I've
declared
MYTYPE *mptr;
what should be the type of 'k'? Should it be ptrdiff_t?
It depends.
In concrete (non-generic) code the type is usually dictated by the
natural properties of the application area. You should normally have a
type that designates the total amount of objects of 'MYTYPE' already.
This type is an obvious candidate for the array index type. For example,
if this is an array of, say, file handles and you use 'unsigned short'
object to store the total number of files, then 'unsigned short' would
be a natural choice for the index type for this array. This, of course,
applies only if you don't care about negative indexing. For negative
indexing you'd have to use either 'short' or 'int', depending on the
required range.
In generic code 'ptrdiff_t' is the first candidate for array index type,
which also supports negative indices. If you don't care about negative
indices or you want to emphasize the fact that negative indices are not
allowed in some context, then you might want to go with 'size_t'. This
unsigned type is large enough for indexing of any array.
However, from the pedantic point of view, 'size_t' is intended to
implement a concept of "object size", while array index is more related
to the concept of "container element count". These two concepts are not
related and using 'size_t' for array indexing is a conceptual error. It
might be more elegant to "hide" the 'size_t' behind a typedef name as
follows
typedef size_t pos_ptrdiff_t;
and use 'pos_ptrdiff_t' for generic non-negative array indexing.