为什么memset sockaddr_in到0 ?

时间:2022-09-11 19:05:01

Is there any definitive guide that says we have to initialize the sockaddr_in struct to zero for a particular reason?

是否有明确的指导说明我们必须将sockaddr_in结构体初始化为零?

// 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
};

Whenever I looked in real code or example or books it always has the code structure similar to the following:

每当我查看真实的代码、示例或书籍时,它的代码结构总是类似于以下内容:

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

I understand that some sources says that the char sin_zero[8] member is there for padding and should be set to zero but why zeroing the rest. Especially when they are initialized in most cases within next few lines of declaration. Even about sin_zero member the beej programming guide said it is not mandatory to zero them out anymore. I have searched for an explanation but nothing to the point turned up. This stack overflow question has some different suggestions on the initialization itself but does not explain why the zeroing is necessary.

我知道有些消息来源说,char sin_zero[8]成员是用来填充的,应该设置为零,但为什么要调零。特别是当它们在接下来的几行声明中初始化时。即使是关于sin_zero的成员,beej编程指南也表示,不再强制将它们排除在外。我找了个解释,但没有找到重点。这个堆栈溢出问题对初始化本身有一些不同的建议,但是没有解释为什么要进行零化。

Is it a legacy practice or there are some real reason I am missing out? Any reference is appreciated.

这是一种传统的做法,还是有一些真正的原因让我错过了?任何引用是感激。

1 个解决方案

#1


6  

Think of it as a default constructor, i.e. it initializes the data to known values (0 in this case). This can help mitigate issues related to non-initialized data when using PODs, like forgetting to set a member, although memset isn't really necessary and you can just value-initialize the struct with sockaddr_in foo{}; (incidentally this also results in better assembly code behind the scenes as the compiler can movq 0 everything instead of calling memset, not that it'll make much difference in 99% of cases).

可以将它看作一个默认的构造函数,即它将数据初始化为已知值(在本例中为0)。这有助于在使用PODs时减轻与未初始化数据相关的问题,比如忘记设置成员,尽管memset并不是必需的,您可以使用sockaddr_in foo{}初始化结构;(顺便说一句,这也会在幕后产生更好的汇编代码,因为编译器可以将所有代码都movq 0而不是调用memset,这并不是说在99%的情况下都有很大的不同)。

If you are absolutely sure you are going to set all members then it isn't strictly necessary, although it can help catch bugs earlier if you forget to initialize something.

如果您绝对确定要设置所有的成员,那么它并不是绝对必要的,尽管如果您忘记初始化某些东西,它可以帮助您及早捕获错误。

#1


6  

Think of it as a default constructor, i.e. it initializes the data to known values (0 in this case). This can help mitigate issues related to non-initialized data when using PODs, like forgetting to set a member, although memset isn't really necessary and you can just value-initialize the struct with sockaddr_in foo{}; (incidentally this also results in better assembly code behind the scenes as the compiler can movq 0 everything instead of calling memset, not that it'll make much difference in 99% of cases).

可以将它看作一个默认的构造函数,即它将数据初始化为已知值(在本例中为0)。这有助于在使用PODs时减轻与未初始化数据相关的问题,比如忘记设置成员,尽管memset并不是必需的,您可以使用sockaddr_in foo{}初始化结构;(顺便说一句,这也会在幕后产生更好的汇编代码,因为编译器可以将所有代码都movq 0而不是调用memset,这并不是说在99%的情况下都有很大的不同)。

If you are absolutely sure you are going to set all members then it isn't strictly necessary, although it can help catch bugs earlier if you forget to initialize something.

如果您绝对确定要设置所有的成员,那么它并不是绝对必要的,尽管如果您忘记初始化某些东西,它可以帮助您及早捕获错误。