允许使用单个 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));
查看 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));