Looking at the source-code of the 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
...
aswell as this:
void DhcpClass::reset_DHCP_lease()
{
// zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
memset(_dhcpLocalIp, 0, 20);
}
Is this really a legal way of accessing/zeroing those arrays, which are fields of a class? Can we really safely assume that they are always in this order and always at a continuous memory location? I believe no but I don't understand why someone wouldn't just write one memset()
for each array, is the performance really that much better?
The performance improvement is not significant, although in an arduino environment, you may be fighting to reduce every byte of generated code (more than execution speed).
As listed, the code is a bad idea, although it will "probably" work OK, that's usually not good enough.
For this case, you could do something like this:
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));
}
};
although you'll have to change the rest of the code to match.
Edited to add:
If the class contains no virtual methods and no other data, you could also do this:
memset(this, 0, sizeof(*this));