Keith Thompson said:
Right, but size_t is maximally portable (whatever that means) while
unsigned long is not.
size_t is the only type that is guaranteed to be able to index any
array. [snip]
Oh? Which paragraphs in the Standard provide that guarantee?
size_t is the type yielded by the sizeof operator. The sizeof
operator may be applied to any type or expression, and yields the
size in bytes of the type or expression. There is no permission
for this to fail.
It has to work only for programs with defined behavior.
Since the number of elements of an array cannot
exceed its size in bytes, it follows that the number of elements
can be represented as a size_t.
Finding the relevant paragraphs in the Standard is left as an
exercise. (You'll likely disagree with some of my reasoning anyway.)
Consider an implementation with SIZE_MAX == 65535, and supplying
an array definition
char too_big[ 100000 ] = {0};
to that implementation. This array definition is legal syntax
and contains no constraint violations -- right? Hence it may be
accepted, either because it's legal or because the implementation
has chosen to define an extension for the undefined behavior. If
it's undefined behavior we're already home free, so let's suppose
for a moment it isn't (ie assume temporarily the declaration is
legal). In that case 'sizeof too_big' would yield a value that
is outside the range of what size_t can represent, which is an
exceptional condition, which is undefined behavior. Hence the
implementation can allow such a declaration, yet size_t cannot
hold a value large enough to index it.
If you disagree with any of the above, would you be so kind
as to supply appropriate section citations or references?