2016-04-12 35 views
0

如以下代碼所示,(uint16_t*)用於s,但(uint32_t*)用於w。爲什麼?該功能用於交換數據包中的目的MAC地址和源MAC地址嗎?(uint16_t *)和(uint32_t *)之間的區別是什麼?

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; 
} 
+6

此代碼違反嚴格別名規則,因此應被視爲展示未定義的行爲。 –

+0

@EugeneSh .:即使考慮到評論(「*假設... *」)中寫的是什麼, – alk

+0

@alk不是嗎?訪問指針爲16/32位整數的64位整數。這些指向不兼容的類型AFAIK .. –

回答

1

該代碼看起來好像是準備應答以太網數據包並交換數據包標頭中的目標和源地址。

MAC地址有48位。即16 ​​+ 32,開發人員決定使用16位數據類型和32位數據類型。正如已經指出的那樣,這可能會或可能無法在現代的,積極優化的編譯器上正常工作。即便如此,它也可能不適用於希望將32位值與內存中的32位對齊的體系結構(例如,ARM)。

考慮到MAC地址可能是一個字節數組,並使用memcpy來移動字節,代碼會更好。

從性能的角度來看,構造可能在使用非常笨的編譯器(考慮今天的標準)時很有用,它不會識別它可能使用大寄存器傳輸來移動數據。在現代編譯器中,即使它運行正常,這些東西甚至會對性能產生負面影響。

相關問題