2014-07-10 11 views
7

C'è qualche guida definitiva che dice che dobbiamo inizializzare sockaddr_in struct su zero per un motivo particolare?Perché memset sockaddr_in a 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 
}; 

Ogni volta che ho guardato nel codice reale o esempio o libri ha sempre la struttura del codice simile al seguente:

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); 

Capisco che alcune fonti dice che il membro char sin_zero[8] è lì per imbottitura e dovrebbe essere impostato su zero ma perché azzerare il resto. Soprattutto quando sono inizializzati nella maggior parte dei casi entro le prossime righe di dichiarazione. Anche su sin_zero member la guida alla programmazione di beej said it is not mandatory to zero them out anymore. Ho cercato una spiegazione ma non è arrivato nulla al punto. Questo stack overflow question ha alcuni suggerimenti diversi sull'inizializzazione stessa, ma non spiega perché è necessario l'azzeramento.

È una pratica legacy o ci sono dei veri motivi per cui mi sto perdendo? Ogni riferimento è apprezzato.

+1

Assicura che non si finisca con il codice che si basa su valori garbage. Tale codice può generare Heisenbugs e altri bug difficili da debugare. –

+1

O semplicemente 'struct sockaddr_in foo = {AF_INET, htons (1025)};' - questo è più corto e azzera solo i membri rimanenti. – MSalters

risposta

6

Consideralo come un costruttore predefinito, cioè inizializza i dati su valori noti (0 in questo caso). Questo può aiutare a mitigare i problemi relativi ai dati non inizializzati quando si usano i POD, come dimenticare di impostare un membro, anche se memset non è realmente necessario e si può semplicemente inizializzare la struct con sockaddr_in foo{}; (incidentalmente ciò comporta anche un migliore codice di assembly dietro le scene come il compilatore possono movq 0 tutto invece di chiamare memset, non che farà molta differenza nel 99% dei casi).

Se si è assolutamente certi di impostare tutti i membri, non è strettamente necessario, anche se può aiutare a individuare i bug in precedenza se si dimentica di inizializzare qualcosa.