4

uint8_t 対 char、移植性、ビット操作、ベスト プラクティス、状況などに関する状況を理解したいと思います。トピックに関する良い読み物を知っていますか?

バイトIOをしたいです。しかしもちろん、char には uint8_t よりも複雑で微妙な定義があります。これが stdint ヘッダーを導入した理由の 1 つだと思います。

ただし、uint8_t を複数回使用すると問題が発生しました。uint8_t の iostream が定義されていないため、数か月前に 1 回。本当によく定義されたバイト IO、つまり uint8_t の読み取りと書き込みを行う C++ ライブラリはありませんか? そうでなければ、需要はないと思います。なんで?

私の最近の頭痛の種は、このコードのコンパイルの失敗から生じています。

uint8_t read(decltype(cin) & s)
{
    char c;
    s.get(c);
    return reinterpret_cast<uint8_t>(c);
}

error: invalid cast from type 'char' to type 'uint8_t {aka unsigned char}'

エラーの理由 これを機能させる方法は?

4

2 に答える 2

2

一般的で、ポータブルで、往復で正しい方法は次のとおりです。

  1. すべてのバイト値を最大 8 ビットで表現できることを API で要求する。
  2. のレイアウト互換性を使用し、charI signed char/ unsigned charO に使用します。
  3. 必要に応じて変換unsigned charuint8_tます。

例えば:

bool read_one_byte(std::istream & is, uint8_t * out)
{
    unsigned char x;    // a "byte" on your system 
    if (is.get(reinterpret_cast<char *>(&x)))
    {
        *out = x;
        return true;
    }
    return false;
}

bool write_one_byte(std::ostream & os, uint8_t val)
{
    unsigned char x = val;
    return os.write(reinterpret_cast<char const *>(&x), 1);
}

いくつかの説明: ルール 1 は、情報を失うことなく値uint8_tを往復変換できることを保証します。ルール 2 は、変数が s で表現されていても、変数に対してunsigned chariostream I/O 操作を使用できることを意味します。unsigned charchar

対称is.read(reinterpret_cast<char *>(&x), 1)の代わりに使用することもできます。is.get()(read一般に、ストリーム カウントが 1 より大きい場合はgcount()on error も使用する必要がありますが、ここでは当てはまりません。)

いつものように、I/O 操作の戻り値を決して無視してはなりません。そうすることは、常にプログラムのバグです。

于 2014-10-05T12:57:46.680 に答える
0

uint8_t の iostream が定義されていないため、数か月前に 1 回。

uint8_tの typedef にすぎませんunsigned char。実際、そうでないマシンを見つけることができるとは思えません。

uint8_t read(decltype(cin) & s)
{
    char c;
    s.get(c);
    return reinterpret_cast<uint8_t>(c);
}

decltype(cin)代わりに使用しstd::istreamてもまったく利点がありません。混乱の原因になる可能性があります。-ステートメントのキャストはreturn必要ありません。chara を aに変換するとunsigned char暗黙的に動作します。

uint8_t の iostream が定義されていないため、数か月前に 1 回。

彼らです。それuint8_t自体ではなく、それが実際に表す型のためであることは間違いありません。operator>> は に対してオーバーロードされていunsigned charます。このコードは機能します:

uint8_t read(istream& s)
{
    return s.get();
}

unsigned charcharは相互にエイリアスできるので、文字列へのreinterpret_cast任意のポインタを に変換して操作することもできます。charunsigned char*

可能な限り最も移植性の高い方法が必要な場合は、Kerrekの回答をご覧ください。

于 2014-10-05T12:52:05.747 に答える