2017-08-26 11 views
2

I次のコード、C++ - 右シフトではない評価を正しく内部IF

if (index > ((v.size() >> 1) - 1)) { } 

v.size()0で、インデックスは実行があればブロックに入らない1ですがあります。しかし、上記のコードを

int limit = (v.size() >> 1) - 1; 
if (index > limit) { } 

に変更し、同じ値のv.size()とindexを使用すると、実行はifブロックに入ります。

この現象はなぜ発生しますか?ありがとう。

+3

おそらく 'v.size()'は 'int'ではないからです。しかし、関連するコンテキストがコードから抜けているため、その動作がわかりません。 – melpomene

+1

ああ、無視された警告... –

+0

これは暗黙の符号なしタイプへの変換によるものです。第2の方法は事実上鋳造である。素敵な質問:私はdownvoteを理解していない。 – Bathsheba

答えて

0

あなたは明らかに符号なし比較を実行しています。返される型はv.size()で、size_t(符号なし整数)です。したがって、式(v.size() >> 1) - 1は、可能な限り大きな符号なし整数を生成します。これを符号付き整数型に変換しない限り、正の比較結果は得られません。

if (index > (((ssize_t)v.size() >> 1) - 1)) { } 

私はそのタイプは、任意のsize_t値を保持することができるように保証されているので、ssize_t使用した場合、負にそれを再解釈している:

減算前ssize_tへの単純なキャストはあなたの問題を解決しますその最上位ビットがセットされる。 intは、通常64ビットプラットフォームでは32ビットしかないので、これは言い難い。したがって、2番目の例のようにintを使用すると、いくつかのビットを切り捨てる可能性があります。

+0

私は人々がまだ間違っているとは信じられません。あなたは符号付きの型にキャストする必要があります。 * unsignedオーバーフロー(*は*うまく定義されています)をキャストするのが遅すぎると、未定義のビヘイビアが返されます(ラップアラウンドは*保証されません)、コンパイラは2の補数ラップアラウンドがあるプラットフォームでもこの未定義の動作を悪用します。ナチュラル)。 'size()'の結果を符号付きの型にキャストし、それに対して算術演算を実行するだけです。 –

+0

@MatteoItalia Afaik、 '(int)(unsigned)i == i'は新しい標準によってよく定義されています。あなたの主張の標準的な参照をお願いしますか? – cmaster

+0

たとえそれが(標準参照?)であっても、我々の場合ではありません - 符号なしの値を通過する符号付きの値との間で往復をしていない場合、オーバーフローした符号なしの値を計算して、値。これは何か有用なものが得られるとは保証されていません(例えば、符号と大きさ、または整数の1の補数表現を持つプラットフォームでは、明らかに正しく動作しませんでした)。 –

関連する問題