transpuesta - programacion ats c++ matrices
¿Es un comportamiento indefinido de `reinterpret_cast` un` T*`a` T(*)[N] `? (2)
Considere el siguiente escenario:
std::array<int, 8> a;
auto p = reinterpret_cast<int(*)[8]>(a.data());
(*p)[0] = 42;
¿Es este comportamiento indefinido ? Creo que es.
a.data()
devuelve unint*
, que no es lo mismo queint(*)[8]
Las reglas de aliasing de tipo en cppreference parecen sugerir que
reinterpret_cast
no es válidoComo programador, sé que la ubicación de memoria señalada por
a.data()
es una matriz de8
objetosint
¿Hay alguna regla que falte que haga que este reinterpret_cast
válido?
Sí, el comportamiento es indefinido.
int*
(el tipo de retorno de a.data()
) es un tipo diferente de int(*)[8]
, por lo que está rompiendo reglas estrictas de alias.
Naturalmente, aunque (y esto es más para el beneficio de los futuros lectores),
int* p = a.data();
es perfectamente válido, como lo es la siguiente expresión p + n
donde el tipo integral n
está entre 0 y 8 inclusive.
Un objeto de matriz y su primer elemento no son punteros interconvertibles * , por lo que el resultado de reinterpret_cast
es un puntero de tipo "puntero a matriz de 8 int
" cuyo valor es "puntero a a[0]
" 1. En otras palabras, a pesar del tipo, en realidad no apunta a ningún objeto de matriz.
Luego, el código aplica la conversión de matriz a puntero al valor l que resultó de la eliminación de la referencia a dicho puntero (como parte de la expresión de indexación (*p)[0]
) 2 . El comportamiento de esa conversión solo se especifica cuando el valor de l se refiere realmente a un objeto de matriz 3 . Dado que el valor de l en este caso no es así, el comportamiento no está definido por la omisión 4 .
* Si la pregunta es "¿por qué un objeto de matriz y su primer elemento no es interconvertible con el puntero?", Ya se ha preguntado: la interconvertibilidad del puntero vs tiene la misma dirección .
1 Ver [expr.reinterpret.cast]/7 , [conv.ptr]/2 , [expr.static.cast]/13 y [basic.compound]/4 .
2 Vea [basic.lval]/6 , [expr.sub] y [expr.add] .
3 [conv.array] : "El resultado es un puntero al primer elemento de la matriz ".
4 [defns.undefined] : el comportamiento indefinido es "comportamiento para el que este documento no impone requisitos", incluido "cuando este documento omite cualquier definición explícita de comportamiento".