Tipos compatibles vs. reglas de alias estrictas
(1)
Es una estrategia común en C la conversión de un tipo a otro, basándose en el hecho de que el diseño de una estructura tiene ciertas garantías. Las bibliotecas como GLib se basan en esto para implementar la herencia orientada a objetos. Básicamente:
struct Base
{
int x;
int y;
};
struct Derived
{
struct Base b;
int z;
};
Esto permite que se asigne un puntero Base*
a la dirección de un objeto Derived
.
Pero también soy consciente de la regla de " alias estricto ", que es la suposición implícita del compilador de que los punteros de tipo diferente no pueden apuntar a la misma dirección. (Esto permite al compilador realizar ciertas optimizaciones).
Entonces, ¿cómo se reconcilian estas dos cosas? Muchas bibliotecas de C, incluidas Glib, CPython, etc., utilizan la estrategia anterior para elegir entre los tipos. ¿Están todos simplemente compilando con banderas como no-strict-aliasing
?
No hay violación de aliasing estricto en este caso. struct Derived
contiene una struct Base
. Este tipo de comportamiento está explícitamente permitido por el estándar de idioma. De C11 6.7.2.1 Especificadores de estructura y unión , párrafo 15:
Un puntero a un objeto de estructura, adecuadamente convertido, apunta a su miembro inicial (o si ese miembro es un campo de bits, luego a la unidad en la que reside), y viceversa.