允许使用单个 memset/assuming 内存布局对多个数组进行清零?

Zeroing-Out multiple arrays with a single memset/assuming memory layout allowed?

查看 Arduino-Ethernet-Library I found this 的源代码:

class DhcpClass {
private:
...
    #ifdef __arm__
        uint8_t  _dhcpLocalIp[4] __attribute__((aligned(4)));
        uint8_t  _dhcpSubnetMask[4] __attribute__((aligned(4)));
        uint8_t  _dhcpGatewayIp[4] __attribute__((aligned(4)));
        uint8_t  _dhcpDhcpServerIp[4] __attribute__((aligned(4)));
        uint8_t  _dhcpDnsServerIp[4] __attribute__((aligned(4)));
    #else
        uint8_t  _dhcpLocalIp[4];
        uint8_t  _dhcpSubnetMask[4];
        uint8_t  _dhcpGatewayIp[4];
        uint8_t  _dhcpDhcpServerIp[4];
        uint8_t  _dhcpDnsServerIp[4];
    #endif
...

以及this:

void DhcpClass::reset_DHCP_lease()
{
    // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
    memset(_dhcpLocalIp, 0, 20);
}

这真的是 accessing/zeroing 那些数组的合法方式吗,它们是 class 的字段?我们真的可以安全地假设它们总是按照这个顺序并且总是在一个连续的内存位置吗?我相信没有,但我不明白为什么有人不为每个数组写一个 memset(),性能真的好得多吗?

虽然在arduino环境下,性能提升并不明显, 您可能正在努力减少生成代码的每个字节(超过执行速度)。

如所列,代码是个坏主意,虽然它“可能”工作正常,但通常不够好。

对于这种情况,您可以这样做:

class DhcpClass {
private:
    struct {
    #ifdef __arm__
        uint8_t  LocalIp[4] __attribute__((aligned(4)));
        uint8_t  SubnetMask[4] __attribute__((aligned(4)));
        uint8_t  GatewayIp[4] __attribute__((aligned(4)));
        uint8_t  DhcpServerIp[4] __attribute__((aligned(4)));
        uint8_t  DnsServerIp[4] __attribute__((aligned(4)));
    #else
        uint8_t  LocalIp[4];
        uint8_t  SubnetMask[4];
        uint8_t  GatewayIp[4];
        uint8_t  DhcpServerIp[4];
        uint8_t  DnsServerIp[4];
    #endif
    } _dhcp;
    void reset_DHCP_lease()
    {
        memset(&_dhcp, 0, sizeof(_dhcp));
    }
};

尽管您必须更改其余代码才能匹配。

编辑添加:

如果class不包含虚拟方法和其他数据,您也可以这样做:

memset(this, 0, sizeof(*this));