2016-03-14 197 views
1

我正在編寫自己的htonl,htons,ntohl和ntohs函數,並且我得到的行爲我不明白。如預期以下作品的代碼:C++參考本地變量與參考

uint16_t htons(uint16_t hostshort) 
{ 
    uint16_t netshort = 0; 
    uint8_t* p = (uint8_t*) (&netshort); 

    p[0] = (uint8_t)((hostshort & 0xFF00) >> 8); 
    p[1] = (uint8_t)((hostshort & 0x00FF) >> 0); 

    return netshort; 
} 

uint16_t ntohs(uint16_t netshort) 
{ 
    uint16_t hostshort = 0; 
    uint8_t* p = (uint8_t*) netshort; 


    hostshort |= ((uint16_t)p[0]) << 8; 
    hostshort |= ((uint16_t)p[1]) << 0; 


    return hostshort; 
} 

的問題是,這種代碼不會在所有的工作:當我在htons netshort刪除&

uint16_t htons(uint16_t hostshort) 
{ 
    uint16_t netshort = 0; 
    uint8_t* p = (uint8_t*) netshort; 

    p[0] = (uint8_t)((hostshort & 0xFF00) >> 8); 
    p[1] = (uint8_t)((hostshort & 0x00FF) >> 0); 

    return netshort; 
} 

uint16_t ntohs(uint16_t netshort) 
{ 
    uint16_t hostshort = 0; 
    uint8_t* p = (uint8_t*) (&netshort); 


    hostshort |= ((uint16_t)p[0]) << 8; 
    hostshort |= ((uint16_t)p[1]) << 0; 


    return hostshort; 
} 

,它返回全零和當我在ntohs中添加它時,它會返回垃圾。有人可以解釋他們如何處理不同嗎?我的理解是,這兩種情況都應該返回一個指向內存中數據開始的指針,但顯然它們的處理方式不同。有沒有什麼隱含的參數發生?

+0

它看起來像你直接將一個值投給一個指針,而沒有采取地址。結果是未定義的。所以有時候它可能會偶然發生。 – wally

+0

uint8_t * p =(uint8_t *)(&netshort);應該是正確的,但是如果它正在返回垃圾,那麼你的ntohs代碼可能會有問題。 –

+0

該代碼在當前表單中不可編譯,投票結束。 – SergeyA

回答

0
uint16_t netshort = 0; 
uint8_t* p = (uint8_t*) netshort; 

這說,採取netshort的值(這是0),並解釋,作爲一個uint8_t*指針。在這種情況下,那將是空的。

這意味着以下幾行,將某些內容分配給該指針是未定義的。

p[0] = (uint8_t)((hostshort & 0xFF00) >> 8); 
p[1] = (uint8_t)((hostshort & 0x00FF) >> 0); 

您需要取本地地址。

uint8_t* p = (uint8_t*) &netshort; 
+0

這甚至不應該編譯。 – SergeyA

+0

@SergeyA解釋爲什麼它「甚至不應該編譯」可能是有用的。 – Ramon

+0

就像我說過的,我太習慣於將警告視爲錯誤,而我忘記了其中的一些警告是沒有的。 – SergeyA