ub это дословно не определенное поведение, до тех пор пока вы итерируетесь в пределах выделеной памяти, поведение коректно, как только попадаете за пределы памяти это ub
Тут получается out-of-bounds array access: (array + i) не валидно если i > N, где N - размер массива. какого массива? того, что получился в выражении array[0] а это массив типа int[5]
ub это дословно не определенное поведение, до тех пор пока вы итерируетесь в пределах выделеной памяти, поведение коректно, как только попадаете за пределы памяти это ub
как упрощение такая логика может сойти, но поведение определено иначе в expr.add#4.2
с точки зрения формальной логики, этот код кошмарен, ужасен и так далее, но с точки зрения компилятора полностью легален, пока array + i в пределах куска памяти выделеного под array[N][M]
с точки зрения формальной логики, этот код кошмарен, ужасен и так далее, но с точки зрения компилятора полностью легален, пока array + i в пределах куска памяти выделеного под array[N][M]
еще раз: поведение кода, который вы написали, в стандарте определено сложнее, чем вы себе представляете
Суть UB не в потенциальном падении или неизвестных значениях объектов. Суть UB в его невозможности в валидной программе. В данном случае компилятор может быть уверен, что случится не больше пяти итераций цикла. Либо size <= 5, либо operator<< кинет исключение. Ещё, к массивам array[1] и array[2] заведомо никто доступа не получает, а значит их не надо занулять.
Суть UB не в потенциальном падении или неизвестных значениях объектов. Суть UB в его невозможности в валидной программе. В данном случае компилятор может быть уверен, что случится не больше пяти итераций цикла. Либо size <= 5, либо operator<< кинет исключение. Ещё, к массивам array[1] и array[2] заведомо никто доступа не получает, а значит их не надо занулять.