缩小C ++中的转换

时间:2014-09-07 12:24:17

标签: c++ standards narrowing

Beej's Guide to Network Programming中,有一个函数旨在提供一种序列化16位整数的可移植方法。

/*
** packi16() -- store a 16-bit int into a char buffer (like htons())
*/ 
void packi16(unsigned char *buf, unsigned int i)
{
    *buf++ = i>>8; *buf++ = i;
}

我不明白为什么语句*buf++ = i;是可移植的,因为将无符号整数(i)赋值给无符号字符(*buf)会导致转换变窄

  • C ++标准是否保证在这种转换中,unsigned int始终被截断,其最低有效8位保留在unsigned char
  • 如果没有,是否有任何解决问题的首选方法?是否足以将函数体更改为以下内容?

    * buf ++ =(i>> 8)& 0xFFFFU; * buf ++ = i& 0xFFFFU;

2 个答案:

答案 0 :(得分:3)

代码假定为8位字节,并且不可移植。

E.g。一些德州仪器的数字信号处理器具有16位字节。

每个字节的位数由CHAR_BIT的{​​{1}}给出。

此外,代码假定<limits.h>是16位,这是不可移植的。

总之,代码不可移植。


RE

  

C ++标准是否保证在这种转换中,unsigned int总是被截断,其最低有效8位保留在unsigned char中?

不,因为C ++标准不保证每个字节的位数是8。

唯一的保证是至少 8位。

无符号算术是保证模块化的。


RE

  

“如果没有,是否有任何解决问题的首选方法?

使用一个简单的循环,迭代unsigned次。

有问题的代码似乎是从这样的循环中提炼出来的,因为sizeof(unsigned)中的后增量完全没有意义(这是*buf++ = i;的最后一次使用。)

答案 1 :(得分:1)

是的,对无符号类型的超出范围分配会调整模数值,使其大于类型中可表示的最大值。在这种情况下,mod UCHAR_MAX+1

无需修复。有些人喜欢写*buf++ = i % 0x100;或等同,以明确这是故意缩小的。