C++unsigned intとintの混用の問題


原文住所:https://blog.qjm253.cn/?p=358
問題の導入
次の奇妙なコードを見てみましょう
#include 
using namespace std;

int main(){
  unsigned int a = 5;
  if(a < -6){           //          
    cout << "unsigned 5 < -6" << endl;
  }
}
  • 上記のコードを実行すると、「unsigned 5<-6」
  • が出力されます.
  • これは少しも科学的ではないように見えます.(:з」∠)_

  • 黒板をたたく
    !!!c++では、1つの式にunsigned intとintが同時にある場合、実行時にintをunsigned intに変換しようとします.-このときintの値が非負であれば、実行結果は当然予想通りである-しかしintの値が負であれば、その値はintの最大値+原値=>実はC++タイプ変換の鍋となり、int回転unsignedであればintの最大値で原値をモールドする
  • intがunsigned intを回転するときにコンパイラがどのように処理するかを検証する
    
    #include 
    
    using namespace std;
    
    int main(){
    unsigned int a = -1;
    unsigned int b = -2;
    
    cout << a << " " << b << endl;
    return 0;
    }
  • 実行上のコード出力は
    4294967295 4294967294
  • である.
  • そのうち232-1=4294967295
  • いくつかの栗を挙げて理解を深める
    
    #include 
    
    
    #include 
    
    
    using namespace std;
    
    int main(){
    
    //Example 1
    u_int a = -5;
    int b = 4;
    if(a + b > 0){
      cout << "(unsigned)-5 + 4 > 0 => and the value is: " << a + b << endl;
    }
    
    //Example 2;
    string s;
    if(s.size() < -1){
      cout << "s.size() < -1" << endl;
    }
    }
  • 以上のコードの出力は
    (unsigned)-5 + 4 > 0 => and the value is: 4294967295
    s.size() < -1
  • である.
  • のうちExample 1はよく理解されており、a+bを実行するとbはunsigned intに変換され、大きな正数
  • になった.
  • でExample 2では、stringオブジェクトのsize()関数も符号なし整数を返すため、unsigned intとintが同じ式で混用されるという問題もある.
  • 説明しない=>u_int <=> unsigned int