typedef struct cmplx { float re; float im; } cmplx_t;¿Se puede convertir la matriz flotante de forma segura en este tipo complejo?
Al igual que:
float s[SIZE*2]; cmplx_t* c = (cmplx_t*) s; // ??¿Qué pasa con el viceversa, estructura para puntero flotante?
cmplx_t c[SIZE]; float* c = (float*) c; // ?? ¿Se puede acceder a una matriz de float a través de un cmplx_t * ?
El lenguaje en el estándar C parece permitir esto. Primero, debemos considerar la conversión de s , que se convierte automáticamente en un puntero, en cmplx_t * . C 2018 6.3.2.3 7 define parcialmente la conversión siempre que la alineación sea correcta. El estándar no garantiza que el requisito de alineación de una estructura sea, como máximo, el requisito de alineación más estricto de sus miembros, pero esto es típico, por lo que la conversión se define en las implementaciones ordinarias de C.
Entonces tenemos que considerar la regla de aliasing. C 2018 6.5 7 dice:
Un objeto tendrá acceso a su valor almacenado solo mediante una expresión lvalue que tenga uno de los siguientes tipos:
— un tipo compatible con el tipo efectivo del objeto,
— una versión cualificada de un tipo compatible con el tipo efectivo del objeto,
— un tipo que es el tipo firmado o no firmado correspondiente al tipo efectivo del objeto,
— un tipo que es el tipo firmado o no firmado correspondiente a una versión calificada del tipo efectivo del objeto,
— un tipo de agregado o unión que incluye uno de los tipos antes mencionados entre sus miembros (incluido, recursivamente, un miembro de un subagregado o unión contenida), o
— un tipo de carácter.
Dado que c apunta a la memoria que se definió como objetos float , float es “un tipo compatible con el tipo efectivo del objeto”, y *c es “un tipo agregado o unión que incluye uno de los tipos mencionados entre sus miembros”. Por lo tanto, *c , c->re y c->im deben ser accesos permitidos por la regla de alias.
El estándar C tampoco especifica que el diseño de cmplx_t tiene el miembro im inmediatamente después del miembro re . Las implementaciones de C pueden insertar relleno entre los miembros y al final de la estructura. Sin embargo, con miembros del mismo tipo, no hay razón para hacerlo, y las implementaciones típicas de C no lo hacen. Por lo tanto, en las implementaciones ordinarias de C, c->re y c->im deberían acceder a los elementos deseados de la matriz float , al igual que c[i].re y c[i].im .
¿Se puede acceder a una matriz de cmplx_t a través de un float * .
El estándar C no define el comportamiento de intentar esto. Para un objeto de tipo cmplx_t , float no es ninguno de los tipos enumerados anteriormente.