I assume that nested std::array cannot assume that memory is strictly contiguous: see for instance: Is the data in nested std::arrays guaranteed to be contiguous? and other related questions. There might be some padding at the end of each sub-array. I cannot find the equivalent information about plain array. Is there a guarantee that all data within a plain array are contiguous in memory or not? for instance with:
uint8_t A[3][7];
Is it safe to say that A[1]-A[0] is 7?
subsidiary question: what should be the behaviour of the sizeof
operator on a multidimensional array and on one of its subarray?
NB ISO/IEC JTC1 SC22 WG21 N4860 §9.3.3.4-9 states:
[Note: When several “array of” specifications are adjacent, a multidimensional array type is created; only the first of the constant expressions that specify the bounds of the arrays may be omitted. [Example: int x3d[3][5][7]; declares an array of three elements, each of which is an array of five elements, each of which is an array of seven integers. The overall array can be viewed as a three-dimensional array of integers, with rank 3 × 5 × 7. Any of the expressions x3d, x3d[i], x3d[i][j], x3d[i][j][k] can reasonably appear in an expression. The expression x3d[i] is equivalent to *(x3d + i); in that expression, x3d is subject to the array-to-pointer conversion (7.3.2) and is first converted to a pointer to a 2-dimensional array with rank 5 × 7 that points to the first element of x3d. Then i is added, which on typical implementations involves multiplying i by the length of the object to which the pointer points, which is sizeof(int)×5 × 7. The result of the addition and indirection is an lvalue denoting the ith array element of x3d (an array of five arrays of seven integers). If there is another subscript, the same argument applies again, so x3d[i][j] is an lvalue denoting the jth array element of the ith array element of x3d (an array of seven integers), and x3d[i][j][k] is an lvalue denoting the kth array element of the jth array element of the ith array element of x3d (an integer). —end example] The first subscript in the declaration helps determine the amount of storage consumed by an array but plays no other part in subscript calculations. —end note]
If I understand it correctly, the data should be contiguous but the "on typical implementations" part bothers me. Thus I still need confirmation. (In which case, I fail to understand why std::array would not have the same guarantee).
[EDIT] "contiguous" notion happens to be misleading in the case of nested sequence and I think that existing post on stackoverflow are not completly clear about that.
Thus my actual questions would be:
- is the memory size only the sum of the size of all elements (no padding), thus here
sizeof(A)
would besizeof(std::uint8_t*3*7)
? - is
A
a contiguous sequence ofstd::uint8_t
meaning that:
void foo(std::uint8_t);
std::uint8_t* p = &A([0][0]);
for (size_t i = 0;i < 3*7;++i,++p) {
foo(*p);
}
are valid?
3. is an expression like std::memset(A,0,sizeof(std::uint8_t)*3*7)
valid?