¿Es un comportamiento indefinido 'reinterpretar cast' a 'T *' a ' T ( * ) [N]`?
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 lo 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álido -
Como programador, sé que la ubicación de la memoria apuntada por
a.data()
es una matriz de8
int
objetos
¿Hay alguna regla que yo soy falta que hace que este reinterpret_cast
válido?
2 answers
Un objeto array y su primer elemento no son interconvertibles por puntero*, así que el resultado de la 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.
El código luego aplica la conversión de matriz a puntero al lvalue que resultó de desreferenciar dicho puntero (como parte de la expresión de indexación(*p)[0]
)2. Esa conversión es el comportamiento solo se especifica cuando el lvalue realmente se refiere a un objeto array3. Dado que el lvalue en este caso no lo hace, el comportamiento es indefinido por omisión4.
*Si la pregunta es " ¿por qué un objeto array y su primer elemento no son pointer-interconvertibles?", ya se ha preguntado: Interconvertibilidad puntero vs tener la misma dirección.
1Véase [expr.reinterpretar.reparto] / 7 , [conv.ptr]/2, [expr.estática.cast] / 13 y [básico.compound] / 4 .
2Véase [básico.lval]/6, [expr.sub] y [expr.add] .
3[conv.array] : "El resultado es un puntero al primer elemento de el array."
4[defns.undefined] : undefined behavior es " comportamiento para el que este documento no impone requisitos", incluyendo "cuando este documento omite cualquier definición explícita de comportamiento".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-25 21:10:02
Sí, el comportamiento es indefinido.
int*
(el tipo devuelto de a.data()
) es un tipo diferente de int(*)[8]
, por lo que está rompiendo las estrictas reglas de aliasing.
Naturalmente, sin embargo (y esto es más para el beneficio de los futuros lectores),
int* p = a.data();
Es perfectamente válido, al igual que la expresión resultante p + n
donde el tipo integral n
está entre 0 y 8 inclusive.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-25 14:44:40