標準ライブラリvector::size()
は、size_t
(符号なしの数値)を返します。 CppConの講演の中で私は誰か(Chandler Carruthだったのですか?)は聞いたことがありますが、これは残念であり、符号付き整数を使うべきだと言います。サイズに符号付き整数または符号なし整数を使用する必要がありますか?
符号付き整数に対してオーバーフローが定義されていないという背景があるため、コンパイラの方がはるかに余裕があります。 Carruth氏は、bzip2のfor
ループインデックスとしてuint8_t
がどのようにしてint8_t
よりも多くのマシン命令を作成することを示しました。マスクとシフトでオーバーフローを明示的にシミュレートする必要があるからです。
私が今作業しているコードでは、厳密にポジティブな特定のサイズがあります。これらはsize_t
と表されます。これは、彼らが否定的ではないことを示しているので、まともではないようです。一方、定義されたモジュラ算術は必要ありません。したがって、符号付き整数が十分に大きい(200になる)限り、符号なし整数は、必要とする算術演算に対して間違ったインタフェースを持ちます。
コードのある時点では、このサイズから0までのループがあります。そして、ループインデックスが減算され、絶対値が取られます。
最近のGCC 7でコンパイルしたとき、size_t - size_t
が明らかに曖昧な値を与えるので、std::abs
の適切なオーバーロードを解決できませんでした。私は、ループインデックスにint
を使用するコードを変更しました:
for (int t1 = 0; t1 < Lt; t1++) {
for (int t2 = 0; t2 < Lt; t2++) {
今abs(t1 - t2)
だけで正常に動作します。しかし、比較t1 < Lt
は、符号付きと符号なしの数値の比較であるため、警告を出します。
正しいアプローチは何ですか?
- 符号なし整数を使用して、負でないものを使用してから、引き算を行う必要があるときはいつでも
static_cast<int>()
を使用します。 - ループインデックスには符号付き整数を使用しますが、コンテナのサイズには符号なし整数を使用します。次に、比較に
static_cast<int>
を使用します。 - どこでも符号付き整数を使用してください。他のライブラリが符号なし整数を返すときは、警告を満たすためにそこに
static_cast<int>
を使用してください。
"これは負の値ではないことを示しているので、まともではないようです*"しかし、モジュラ算術に従うことになっていますか? – juanchopanza
符号付きの値が必要な場合は、 'int'ではなく' ssize_t'(余分な 's')に注意してください。 –
[This](https://stackoverflow.com/questions/10040884/signed-vs-unsigned-integers-for-lengths-counts)は面白いかもしれません。 –