unsigned intは、少なくとも0〜65536の範囲の値を格納できるようにするために必要です。int64_t(からのポータブルバージョン)は、-(2 63 -1)と263の<stdint.h>
間の値を格納できます。ここで問題があります。これは、unsigned intの長さが64ビットであり、int64_tの範囲外の値を表す可能性があることです(C標準の§5.2.4.2.1p1および以下のセクションを参照)。
標準の内容は次のとおりです。
6.3.1.3符号付きおよび符号なし整数
- 整数型の値を_Bool以外の整数型に変換する場合、その値を新しい型で表すことができれば、変更はありません。
- それ以外の場合、新しいタイプが符号なしの場合、値が新しいタイプの範囲内になるまで、新しいタイプで表すことができる最大値より1つ多い値を繰り返し加算または減算することにより、値が変換されます。60)
- それ以外の場合、新しいタイプは署名され、値を表すことができません。結果が実装定義であるか、実装定義のシグナルが発生します。
60)ルールは、特定のタイプの式の値ではなく、数学的な値の算術を記述します。
計算例外に対応する実装定義の信号を無視することは、未定義の動作です。
符号なしから符号付きへの変換の場合は、動作を明示的に定義することをお勧めします。飽和が最も簡単です。unsignedint値がINT64_MAXより大きい場合、変換の結果はINT64_MAXになります。これはのように見えますx > INT64_MAX : INT64_MAX ? x
。unsigned int x = UINT_MAX; ++x == 0
int64_tにパディングが含まれないことが保証されているため、int64_tのLIAスタイル(例)をラップすることは可能ですが、移植性を保証するにはさらに作業が必要です。(x & INT64_MIN) > INT64_MAX ? -(x & INT64_MAX) : x & INT64_MAX
あなたのint64がC標準のint64_tと同じ表現を持つという主張を見つけることができれば、のようなものを提案します。