2016-03-14 135 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