If I index an array with an unsigned int or a long, is it being implicitly cast into an int, or is the type somehow maintained? If I use large unsigned int as index, is it cast into a negative int? Is this defined behavior or another one of those compiler-can-do-what-it-wants quirks?
2 Answers
Since arr[i] is per definition equivalent to *((arr) + (i)), the rules for pointer arithmetic is found below the additive operators +, - in the C standard.
C17 6.5.6:
Constraints
For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type.
Everywhere in the following text, the term integer type is used. Meaning that any integer type can be use and there are no implicit promotions.
Save for the special scenario where we subtract one pointer from another, in which case the result is the integer type ptrdiff_t.
C specifies no relation between integer types and pointers, likely for the reason that on a traditional computer, there's not necessarily any relation between the CPU data word size and the address bus width. But the C standard doesn't even say or mandate that pointers equal addresses.
The exact nature, width and ranges of the underlying addresses are beyond the scope of the C language and therefore entirely implementation-defined.
Comments
Concerning array and not pointer access:
If I index an array with an
unsigned intor along, is it being implicitly cast into anint, or is the type somehow maintained?
The index is not implicitly cast.
There is no type maintained after the access concerning the index.
// Even though 123 is an `int`, indexes are not limited to type `int`
some_type arr[123];
unsigned int ui = tbd; // arr[ui] valid if ui in the [0...122] range.
unsigned long lo = tbd; // arr[ui] valid if lo in the [0...122] range.
If I use large
unsigned intas index, is it cast into a negative int?
No. Still the value of the index must be in the valid range. E.g. [0...122] in above example.
Is this defined behavior or another one of those compiler-can-do-what-it-wants quirks?
Array byte sizes are limited to [1 ... SIZE_MAX]. An allocated array may be larger.
Array indexes are limited to [0 ... SIZE_MAX-1].
SIZE_MAX is at least 65535.
Some system may impose additional limits.
With a pointer the indexing limits apply to the target object.
some_type arr[123];
some_type *ptr = &arr[1];
int i = tbd; // ptr[i] valid if i in the [-1...121] range.
unsigned u = tbd; // ptr[u] valid if u in the [ 0...121] range.
// ptr[(unsigned)-1]` is not valid.
2 Comments
SIZE_MAX that's apparently just an upper limit and the actual maximum size might come as a surprise. Why is the maximum size of an array "too large"?
a[i]andi[a]are equivalent to*(a+i). So the question really is about pointer addition, which is the addition of a pointer type and an integer type.( )cast operator.