3

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?

10

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

8 Comments

you should just understand what is pod and what isn't. after you do code in question is a good way
@Алексей Неудачин by pod do you mean == plain old data?
Note: this is only valid if the type is standard-layout, but honestly this could be replaced with _dhcp = {}; and called done.
@Mgetz, the struct has more members than listed in the question
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.