Тип, удаляющий структуру в C и C ++ через объединение

Я скомпилировал это в gcc и g ++ с педантичным, и я не получаю предупреждение ни в одном из них:

#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;
}

Это законно делать в C и C ++? Я читал о типовом наказании, но я не понимаю. Являетсяfoo(&c.u.b) отличается отfoo((struct b *)&c.u.a)? Разве они не будут точно такими же? Это исключение для структур в объединении (из C89 в 3.3.2.3) говорит:

Если объединение содержит несколько структур, которые имеют общую начальную последовательность, и если объект объединения в настоящее время содержит одну из этих структур, разрешается проверять общую начальную часть любой из них.Две структуры имеют общую начальную последовательность, если соответствующие члены имеют совместимые типы для последовательности из одного или нескольких начальных элементов.

В союзе первый членstruct a являетсяstruct a *nextи первый членstruct b являетсяstruct b *next, Как вы можете видеть указатель наstruct a *next написано, а затем в foo указатель наstruct b *next читается Это совместимые типы? Они оба являются указателями на структуру, а указатели на любую структуру должны быть одинакового размера, поэтому они должны быть совместимы, а расположение должно быть одинаковым, верно? Это нормально читатьi из одной структуры и писать в другую? Я совершаю какой-либо тип алиасинга или нарушения типа?

Ответы на вопрос(2)

Ваш ответ на вопрос