Escriba puntear una estructura en C y C ++ a través de una unión

He compilado esto en gcc y g ++ con pedante y no recibo ninguna advertencia en ninguno de los dos:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct a {
    struct a *next;
    int i;
};

struct b {
    struct b *next;
    int i;
};

struct c {
    int x, x2, x3;
    union {
        struct a a;
        struct b b;
    } u;
};

void foo(struct b *bar) {
    bar->next->i = 9;
    return;
}

int main(int argc, char *argv[]) {
    struct c c;
    memset(&c, 0, sizeof c);
    c.u.a.next = (struct a *)calloc(1, sizeof(struct a));
    foo(&c.u.b);
    printf("%d\n", c.u.a.next->i);
    return 0;
}

¿Es legal hacer esto en C y C ++? He leído sobre el tipo de letra pero no entiendo. Esfoo(&c.u.b) diferente defoo((struct b *)&c.u.a)? ¿No serían exactamente lo mismo? Esta excepción para estructuras en una unión (de C89 en 3.3.2.3) dice:

Si una unión contiene varias estructuras que comparten una secuencia inicial común, y si el objeto de unión actualmente contiene una de estas estructuras, se permite inspeccionar la parte inicial común de cualquiera de ellas.Dos estructuras comparten una secuencia inicial común si los miembros correspondientes tienen tipos compatibles para una secuencia de uno o más miembros iniciales.

En la unión el primer miembro destruct a esstruct a *nexty el primer miembro destruct b esstruct b *next. Como puede ver un puntero astruct a *next está escrito, y luego en foo un puntero astruct b *next es leído. ¿Son tipos compatibles? Ambos son punteros a una estructura y los punteros a cualquier estructura deben ser del mismo tamaño, por lo que deben ser compatibles y el diseño debe ser el mismo, ¿verdad? ¿Está bien leer?i de una estructura y escribir a la otra? ¿Estoy cometiendo algún tipo de alias o violación de tipo?

Respuestas a la pregunta(4)

Su respuesta a la pregunta