简体   繁体   中英

What is the difference between (uint16_t*) and (uint32_t*)?

As shown in the following code, (uint16_t*) is used for s , but (uint32_t*) is used for w . Why? Is this function used for swapping destination MAC address and source MAC address in a packet?

static inline void      
swap_mac_addr(uint64_t pkt_ptr)
{
     uint16_t s;
     uint32_t w;

     /* assuming an IP/IPV6 pkt i.e. L2 header is 2 byte aligned, 4 byte non-aligned */
     s = *(uint16_t*)pkt_ptr;
     w = *(uint32_t*)(pkt_ptr+2);
     *(uint16_t*)pkt_ptr = *(uint16_t*)(pkt_ptr+6);                                                                                  
     *(uint32_t*)(pkt_ptr+2) = *(uint32_t*)(pkt_ptr+8);
     *(uint16_t*)(pkt_ptr+6) = s;
     *(uint32_t*)(pkt_ptr+8) = w;
}   

The code looks as if it would be preparing an answer to an Ethernet packet and swaps destination and source address in the packet header.

A MAC address has 48 bits. That is 16+32, the developer has decided to use a 16bit data type plus a 32 bit data type. As has been pointed out already, this might or might not work properly on a modern, aggressively optimizing compiler. Even then, it might not work on an architecture that wants to see 32bit values aligned to 32bits in memory (ARM, for example).

The code would be better off considering the MAC address as maybe an array of bytes and use memcpy to move the bytes around.

Seen from the viewpoint of performance, that construct might have been helpful when using a pretty dumb compiler (considering today's standards) that wouldn't recognize it could use large register transfers to move the data around. On a modern compiler, even if it worked properly, such stuff could even have a negative performance impact.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM