1

Beejの 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;

4

2 に答える 2

3

コードは 8 ビット バイトを想定しており、移植性がありません。

たとえば、テキサス インスツルメンツの一部のデジタル信号プロセッサには 16 ビット バイトがあります。

バイトあたりのビット数はCHAR_BITfromで与えられ<limits.h>ます。

また、コードunsignedは 16 ビットであると想定しているため、移植性がありません。

要約すると、コードは移植性がありません。


C++ 標準は、そのような変換で unsigned int が常に切り捨てられ、その最下位 8 ビットが unsigned char に保持されることを保証していますか?

いいえ、C++ 標準では 1 バイトあたりのビット数が 8 であることを保証していないためです。

唯一の保証は、少なくとも8 ビットであることです。

ただし、符号なし算術演算はモジュラーであることが保証されています。


そうでない場合、問題を解決するための好ましい方法はありますか?

回数を繰り返す単純なループを使用しますsizeof(unsigned)

のポストインクリメントはまったく無意味なので、問題のコードはそのようなループから抽出されたように見えます*buf++ = i;(これが の最後の使用ですbuf)。

于 2014-09-07T12:34:34.747 に答える