Some of the sockets/unix networking struct
objects behave and are intended to be used as if they were a union
type. In other words, many functions in the sockets API take a struct sockaddr*
, and it is expected that the client will call these functions with a range of struct
types by casting pointers to different types.
For example, a sockaddr_in
(ipv4) and sockaddr_in6
(ipv6) struct may be cast to a struct sockaddr*
by taking the address of the object and performing a pointer type cast.
I am curious to know why there is no explicit union
type involved here, even though these objects are intended to be used and behave as if they were a union
type.
I hope the question makes sense and is clear enough? This is a somewhat abstract or difficult to describe question.
union
behave somewhat polymorphically. Perhaps this comment helps to explain what I am thinking about here.
The sockets API is very old, dating back to the 1980s. The ANSI C standard was ratified only in 1989. Programmers using C were not concerned with academic undefined behavior issues, like that certain type punning is formally well-defined if done through a union
, but not otherwise.
C unions are cumbersome to use, due to introducing extra members. I think ISO C still does not have transparent unions.
If you make a union
out of all the possible structures, the resulting object will have a size large enough to contain all of them. That may be undesirable.
Only fairly recently (in terms of the long history of the API) did POSIX add the type struct sockaddr_storage
which has this property of being large enough to define storage for any sockaddr
type, but that's normally only used for that specific purpose.
Code not working with any type might not want the overhead of the extra storage not needed by its type.
The API designers opted for the simple "OOP" technique of just casting pointers from a "derived" class like struct sockaddr_in *
to a "base" type like struct sockaddr
, ensuring that any common members were put in front, so that for instance the address family could be accessed through any type to tell that the struct sockaddr
is really struct sockaddr_in
, due to its tag being AF_INET
.
This is not unheard of C programs, not just the socket API of POSIX.
In addition to what the other answers have said, many new protocols have appeared since the early days when sockaddr
was introduced. Those protocols use their own unique sockaddr_...
struct types (ie, sockaddr_un
for UNIX domains, sockaddr_bth
for Bluetooth, etc), sometimes in separate libraries/headers, but they are still "compatible" with socket APIs that take basic sockaddr*
pointers. It would be much more difficult to develop new protocols if all of the structs had to be declared in a single union
in one place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With