I have always thought the next example is undefined behaviour (accessing array out of bounds):
int main()
{
int* a= new int[3];
a[0] = 100;
a++;
unsigned long index = 0;
printf("%d\n", a[-1]);
printf("%d\n", a[index - 1]);
printf("%ul\n", index - 1);
}
However, this outputs just fine:
100
100
4294967295l
Why doesn't underflow happen in subscript operator?
Why doesn't underflow happen in subscript operator?
printf("%d\n", a[-1]);
has defined behaviour. Pointer arithmetic works with any integral type, so the signed int
value -1
is added to a
, resulting in an in-bounds access, to an element that was initialised.
printf("%d\n", a[index - 1]);
has undefined behaviour. index - 1
is a mixed-rank integral expression, and unsigned long
has a greater1 rank than int
, so it is an unsigned expression, equivalent to std::numeric_limits<unsigned long>::max()
. Adding this to a
is out of bounds, thus undefined behaviour. Because the standard places no requirements on the observed behaviour, printing 100 is conformant.
printf("%ul\n", index - 1);
has undefined behaviour. lu
is the correct format specifier for unsigned long
.
unsigned short
to have defined behaviour.