2014-07-10 13 views
7

Czy istnieje jakiś ostateczny przewodnik, który mówi, że musimy zainicjować strukturę sockaddr_in na zero z konkretnego powodu?Dlaczego zestawienie sockaddr_in to 0

// IPv4 AF_INET sockets: 
struct sockaddr_in { 
    short   sin_family; // e.g. AF_INET, AF_INET6 
    unsigned short sin_port;  // e.g. htons(3490) 
    struct in_addr sin_addr;  // see struct in_addr, below 
    char    sin_zero[8]; // zero this if you want to 
}; 

Ilekroć spojrzał w rzeczywistym kodu lub np czy książek to zawsze ma strukturę kodu podobnego do poniższego:

struct sockaddr_in foo; 
memset(&foo, 0, sizeof(foo)); 
foo.sin_port = htons(1025); 
foo.sin_family = AF_INET; 
inet_pton(AF_INET, "10.0.0.1", &foo.sin_addr); 

Rozumiem, że niektóre źródła podają, że człon char sin_zero[8] jest dla dopełnienia i powinno być ustawione na zero, ale dlaczego zeruje resztę. Zwłaszcza gdy są one inicjowane w większości przypadków w ciągu kilku kolejnych linii deklaracji. Nawet o sin_zero członek przewodnik programowania beej said it is not mandatory to zero them out anymore. Szukałem wyjaśnienia, ale nic nie wskazywało na to. Ten stack overflow question ma różne sugestie dotyczące samej inicjalizacji, ale nie wyjaśnia, dlaczego zerowanie jest konieczne.

Czy jest to starsza praktyka czy istnieje jakiś prawdziwy powód, dla którego tęsknię? Wszelkie odniesienia są mile widziane.

+1

Zapewnia to, że nie kończy się na kodzie polegającym na wartościach śmieci. Taki kod może generować Heisenbugs i inne błędy, które są trudne do debugowania. –

+1

Lub po prostu 'struct sockaddr_in foo = {AF_INET, htons (1025)};' - Jest krótszy i zeruje tylko pozostałe elementy. – MSalters

Odpowiedz

6

Wyobraź sobie, że jest to domyślny konstruktor, to znaczy inicjalizuje dane do znanych wartości (w tym przypadku 0). Może to pomóc w złagodzeniu problemów związanych z nie zainicjalizowanymi danymi podczas korzystania z POD, np. Zapominając o ustawieniu członka, chociaż memset nie jest naprawdę konieczne i można po prostu zainicjować wartość struct za pomocą sockaddr_in foo{}; (przypadkowo powoduje to również lepszy kod zespołu za sceny jako kompilator mogą wywoływać wszystko, zamiast dzwonić pod numer memset, ale nie będą miały znaczącej różnicy w 99% przypadków).

Jeśli jesteś absolutnie pewny, że ustawisz wszystkich członków, nie jest to absolutnie konieczne, chociaż może pomóc złapać błędy wcześniej, jeśli zapomnisz zainicjować coś.