3 ms·
> In C, if you have a declaration `int x[2][3];`, the expression `x[0][4]` is a legal way to access one of the elements--it's only UB to go outside the bounds o
by LegionMammal978 3y ago
> In C, if you have a declaration `int x[2][3];`, the expression `x[0][4]` is a legal way to access one of the elements--it's only UB to go outside the bounds of x as a whole, not individual rows.
Even though multidimensional arrays are laid out contiguously in C/C++, it doesn't follow that indexing can traverse from one row to the next. By C17 6.5.6/8, pointer-integer addition can only create pointers to other elements (or one past the last element) of the same array object that the original pointer came from. However, an int[2][3] array has two int[3] arrays as elements, and each of those arrays has three int objects as elements. The int objects are not all elements of the same array (the standard's definition of an array element, 6.2.5/20, doesn't apply recursively), so you aren't allowed to index between them with expressions like (x[0] + 4).
Compilers seem to be pretty lenient about this in practice, though, only optimizing out out-of-bounds accesses when they exit the complete object. But at least Clang's UBSan will complain if you try to index between rows [0].
[0] https://godbolt.org/z/GYosP39Mc https://godbolt.org/z/GYosP39Mc