2014-07-10 22 views
7

Có hướng dẫn dứt khoát nào nói rằng chúng ta phải khởi tạo cấu trúc sockaddr_in về 0 vì một lý do cụ thể không?Tại sao memset sockaddr_in là 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 
}; 

Bất cứ khi nào tôi nhìn vào mã thực hoặc ví dụ hoặc sách nó luôn luôn có cấu trúc mã tương tự như sau:

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

Tôi hiểu rằng một số nguồn tin nói rằng char sin_zero[8] thành viên là có cho đệm và nên được đặt thành 0 nhưng tại sao không đánh số còn lại. Đặc biệt là khi chúng được khởi tạo trong hầu hết các trường hợp trong vài dòng khai báo tiếp theo. Ngay cả về thành viên sin_zero, hướng dẫn lập trình beej said it is not mandatory to zero them out anymore. Tôi đã tìm kiếm một lời giải thích nhưng không có gì để điểm được bật lên. Điều này stack overflow question có một số gợi ý khác nhau về khởi tạo chính nó nhưng không giải thích tại sao zeroing là cần thiết.

Đây có phải là thực tiễn kế thừa hoặc có một số lý do thực sự mà tôi bỏ lỡ không? Bất kỳ tài liệu tham khảo được đánh giá cao.

+1

Nó đảm bảo rằng bạn không kết thúc với mã dựa vào giá trị rác. Mã như vậy có thể tạo ra Heisenbugs và các lỗi khác khó gỡ lỗi. –

+1

Hoặc chỉ 'struct sockaddr_in foo = {AF_INET, htons (1025)};' - ngắn hơn và chỉ các thành viên còn lại. – MSalters

Trả lời

6

Hãy coi đó là một hàm tạo mặc định, tức là nó khởi tạo dữ liệu thành các giá trị đã biết (0 trong trường hợp này). Điều này có thể giúp giảm thiểu các vấn đề liên quan đến dữ liệu không được khởi tạo khi sử dụng POD, như quên đặt thành viên, mặc dù memset không thực sự cần thiết và bạn chỉ có thể tạo giá trị khởi tạo cấu trúc với sockaddr_in foo{}; (điều này cũng dẫn đến mã lắp ráp tốt hơn sau các cảnh như trình biên dịch có thể movq 0 mọi thứ thay vì gọi memset, không phải là nó sẽ tạo ra sự khác biệt nhiều trong 99% các trường hợp).

Nếu bạn hoàn toàn chắc chắn rằng bạn sẽ thiết lập tất cả các thành viên thì điều đó là không cần thiết, mặc dù nó có thể giúp bắt lỗi trước đó nếu bạn quên khởi tạo một cái gì đó.

Các vấn đề liên quan