Everywhere I look, I see the following piece of code:
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;
In C++, the same idea is usually expressed as
sockaddr_in addr = {}; // unneccesary(?) value-initialzation
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;
Yet nowhere I look (in terms of official documentation) do I see any requirement to zero out the structure before setting those members! Yes, usually BSD sockets implementations do have a sin_zero
member defined for sockaddr_in
, but they always say the member is needed for padding, to align the size of sockaddr_in
with sockaddr
. And they never request one to put any specific contents into it.
Is there any real, documentation proven need to zero out the struct?
P.S.
Before you VTC the question as a duplicate of one of several SO questions regarding memset
on sockaddr_in
, please make sure the question your are suggesting as a duplicate has any links to official documentation rather than just speculation on 'initializing of unused members just in case'.
Short answer:
The IEEE Standard doesn't require it.
Long(er) answer:
The IEEE Standard 1003.1 specifies that the definition of
sockaddr_in
is (Emphasis mine):Note that, unlike the definition for
sockaddr_in6
, which specifies that it should be zeroed out:There is no similar wording for
sockaddr_in
. However, such lack of wording gives platform implementors enough ambiguity to make their own requirements about zeroing out all or part ofsockaddr_in
.Note that the definition of
sockaddr_in
used to require asin_zero
field to pad out the structure to make it compatible withsockaddr
structures:And it's with
sin_zero
we find a discrepancy between Windows and Linux. Even though the field was removed from the official definition, both Windows and Linux implementation still include it (because it's not explicitly illegal thanks to the wording "at least").Whether
sin_zero
always requires zeroing out or not for Windows platforms isn't clear, but in this blog post the writer did some digging and came up with the following:For the part about "It's required by specification to clear
sin_zero
", I could only find the following Windows documentation (for Winsock Kernel) appearing to support the claim:However, I can find no similar wording for Linux.
So to conclude, it appears that in some architectures you need to zero out at least one field, while in others you don't. I think it's best to be safe and zero out everything.
A bit late to the party - but here's something relevant, that I think is a worthwhile addition to the discussion. In the 3rd edition of the “Unix Network Programming” of Richard Stevens, on page 70, there's this:
“...when binding non-wildcard IPv4 address, this member must be zero (pp. 731-732 of TCPv2)”
Stevens here mentions "TCPv2" - and the "member" he is talking about is
sin_zero
. This seems to fit with the profile of your question... at least in the context ofbind
-ing. Notice that he uses the word must.Whether this answer qualifies for "official documentation" or not... I leave that up to you! But as others have said, regardless of whether it's official or not... it's for sure a good idea to
memset
to zero (or use= {0};
at structure variable definition). In this way, you have one less thing to worry about...