Hi, After reading more about transparent_unit, here's my idea of a fix for the API. old_api() is an example for the libc functions that accept a `struct sockaddr *`, and user_code() is an example for user code functions that handle sockaddr structures. The interface would be the same as it is currently, but the implementation inside libc would change to use a union. In user code, uses of sockaddr_storage would be made safe with these changes, I believe, and new code would be simpler, since it wouldn't need casts. void old_api(union my_sockaddr_ptr *sa); struct sockaddr_storage { union { struct { sa_family_t ss_family; }; struct sockaddr_in sin; struct sockaddr_in6 sin6; struct sockaddr_un sun; // ... }; }; union [[gnu::transparent_union]] sockaddr_ptr { struct sockaddr_storage *ss; struct sockaddr *sa; }; void old_api(struct sockaddr_storage *ss) { // Here libc uses the union, so it doesn't invoke UB. ss->sun.sa_family = AF_UNIX; //... } void user_code(void) { struct my_sockaddr_storage ss; // object definition // ... old_api(&ss); // The transparent_union allows no casts. switch (ss.ss_family) { // This is safe too. // thanks to common initial sequence within a union. } } This would in fact deprecate plain `struct sockaddr`, as Bastien suggested. Cheers, Alex --