正在缩小C++中的转换

Narrowing conversion in C++

本文关键字:转换 C++ 缩小      更新时间:2023-10-16

在Beej的网络编程指南中,有一个函数旨在提供一种可移植的方式来序列化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;

代码采用8位字节,这是不可移植的。

例如,一些德州仪器的数字信号处理器具有16位字节。

每个字节的比特数由CCD_ 6从CCD_ 7给出。

此外,该代码假定unsigned是16位,这是不可移植的。

总之,该代码是不可移植的。


Re

"C++标准是否保证在这样的转换中,无符号int总是被截断,并且它的最低有效位8保留在无符号char中?

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

唯一的保证是至少为8位。

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


Re

”如果没有,有没有更可取的方法来解决这个问题?

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

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

是的,对无符号类型的超范围赋值会将值调整为模1,大于该类型中可表示的最大值。在这种情况下,修改UCHAR_MAX+1

无需修复。有些人喜欢写*buf++ = i % 0x100;或等效内容,以表明这是有意缩小范围。