c++undefined-behaviorstdlaunder

Why is it undefined behavior to std::launder a multidimensional array?


I was reading the docs for std::launder and I came across this code snippet:

int x2[2][10];
auto p2 = std::launder(reinterpret_cast<int(*)[10]>(&x2[0][0]));
// Undefined behavior: x2[1] would be reachable through the resulting pointer to x2[0]
// but is not reachable from the source

What is int(*)[10] supposed to mean?
I read it as "array of ints of size 10". But then the UB comment doesn't make sense to me. x2[0] and p2 are both size 10. As long as you don't try to do arithmetic above the 10th element (eg p2+10) then you shouldn't be in UB land, right?

The closest thing I found to an answer is provided in 71631428, but it doesn't fully answer my questions.

Edit:

What is int(*)[10] supposed to mean?

I finally found the answer and it is so basic knowledge: "Pointer to an array of ints of size 10". The other question about UB remains. So I will edit the title appropriately.


Solution

  • Short answer: C++ standards require that only elements reachable through the original object’s type should be accessed.

    Long Answer:

    Have a look at what the memory layout of x2 may look like

    x2[0][0], x2[0][1], ..., x2[0][9], x2[1][0], x2[1][1], ..., x2[1][9]
    

    The addresses are contagious and the elements are laid in a single block of memory that you can iterate over.

    This piece of code reinterpret_cast<int(*)[10]>(&x2[0][0]); tells the compiler to treat the memory at x2[0][0] as the start of an array of 10 ints however this address is nothing but a single integer inside a larger container.

    But because it's C++, and you are using reinterpret_cast, you can indeed do something like this

    (*p2)[11] = 2; /* this code should access x2[1][1] */

    So with all that said (elements are contiguous in memory and in C++ you can do almost anything), a line like this (*p2)[11] = 2; will work but since you can't access x2[11] from the address given by the source &x2[][], this code is identified by the standards as an undefined behavior.