arr.size()
- это тип данных без знака , обычно size_t
. При i
без знака i >= 0
всегда равно true
. Вычитание 1
из переменной без знака, равной 0
, приводит к наибольшему количеству, которое может содержать тип. В результате он будет работать бесконечно.
То, что тогда произойдет, неизвестно, так как ваш индекс массива превратится в гигантское значение c, а arr[i]
будет иметь неопределенное поведение для значений >= arr.size()
. Если у вас есть int
вместо auto
, он работает, потому что i--
приведет к тому, что он в конечном итоге будет -1
, и тогда i >= 0
будет false
, выходя из l oop.
Объяснение этого поведения ролловера можно найти здесь :
Арифметическое целое число без знака c всегда выполняется по модулю 2 n , где n
- это число битов в этом конкретном целом числе. Например, для unsigned int добавление одного к UINT_MAX
дает 0
, а вычитание одного из 0 дает UINT_MAX
.
Так, для size_t
, вычитание 1
из 0
приводит к SIZE_MAX
, который обычно имеет значение 18446744073709551615
.