.SH STANDARDS
C11 and later.
.SH EXAMPLES
+The following code demonstrates how to write
+a macro similar to C++'s
+.BR \%static_cast (),
+which will allow casting safely between a limited set of types.
+It is useful for example when calling
+system calls or library functions that use compatible structures,
+like for example
+.BR bind (2)
+with
+.BR \%sockaddr (3type).
+.IP
+.EX
+/* This code is in the public domain. */
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#define sockaddr_cast(t, p) \e
+ _Generic(&*(p), \e
+ struct sockaddr *: \e
+ _Generic((typeof_unqual(t)) NULL, \e
+ struct sockaddr_in *: (t) (p), \e
+ struct sockaddr_in6 *: (t) (p), \e
+ struct sockaddr_un *: (t) (p), \e
+ default: (p)), \e
+ struct sockaddr **: \e
+ _Generic((typeof_unqual(t)) NULL, \e
+ struct sockaddr_in **: (t) (p), \e
+ struct sockaddr_in6 **: (t) (p), \e
+ struct sockaddr_un **: (t) (p), \e
+ default: (p)), \e
+ const struct sockaddr *: \e
+ _Generic((t) NULL, \e
+ const struct sockaddr_in *: (t) (p), \e
+ const struct sockaddr_in6 *: (t) (p), \e
+ const struct sockaddr_un *: (t) (p), \e
+ default: (p)), \e
+ \e
+ struct sockaddr_in *: \e
+ _Generic((typeof_unqual(t)) NULL, \e
+ struct sockaddr *: (t) (p), \e
+ default: (p)), \e
+ struct sockaddr_in **: \e
+ _Generic((typeof_unqual(t)) NULL, \e
+ struct sockaddr **: (t) (p), \e
+ default: (p)), \e
+ const struct sockaddr_in *: \e
+ _Generic((t) NULL, \e
+ const struct sockaddr *: (t) (p), \e
+ default: (p)), \e
+ \e
+ struct sockaddr_in6 *: \e
+ _Generic((typeof_unqual(t)) NULL, \e
+ struct sockaddr *: (t) (p), \e
+ default: (p)), \e
+ struct sockaddr_in6 **: \e
+ _Generic((typeof_unqual(t)) NULL, \e
+ struct sockaddr **: (t) (p), \e
+ default: (p)), \e
+ const struct sockaddr_in6 *: \e
+ _Generic((t) NULL, \e
+ const struct sockaddr *: (t) (p), \e
+ default: (p)), \e
+ \e
+ struct sockaddr_un *: \e
+ _Generic((typeof_unqual(t)) NULL, \e
+ struct sockaddr *: (t) (p), \e
+ default: (p)), \e
+ struct sockaddr_un **: \e
+ _Generic((typeof_unqual(t)) NULL, \e
+ struct sockaddr **: (t) (p), \e
+ default: (p)), \e
+ const struct sockaddr_un *: \e
+ _Generic((t) NULL, \e
+ const struct sockaddr *: (t) (p), \e
+ default: (p)), \e
+ \e
+ default: \e
+ (p) \e
+ )
+
+socklen_t slen;
+struct sockaddr_un sun;
+
+slen = sizeof(ss);
+getsockname(sfd, sockaddr_cast(struct sockaddr *, &sun), &slen);
+.EE
+.PP
The following program demonstrates how to write
a replacement for the standard
.BR imaxabs (3)
function, which being a function can't really provide what it promises:
seamlessly upgrading to the widest available type.
-.PP
+.IP
.\" SRC BEGIN (_Generic.c)
.EX
#include <stdint.h>