unsigned int (c++) vs uint (c#)

前端 未结 3 809
难免孤独
难免孤独 2021-02-05 00:39

Following is the c# code:

   static void Main(string[] args)
    {
        uint y = 12;
        int x = -2;
        if (x > y)
            Console.WriteLine(\         


        
相关标签:
3条回答
  • 2021-02-05 01:19

    In C++, when you compare an unsigned int and a signed int, the signed int is converted to unsigned int. Converting a negative signed int to an unsigned int is done by adding UINT_MAX + 1, which is larger than 12 and hence the result.

    In C#, if you are getting the opposite result then it means that in C# both the expressions are being converted to signed int signed long (long or System.Int64)1 and then compared.

    In C++, your compiler must have given you the warning:

    warning: comparison between signed and unsigned integer expressions

    Rule:
    Always take warnings emitted by the compiler seriously!

    1 As rightly pointed out by svick in comments.

    0 讨论(0)
  • 2021-02-05 01:27

    C++ and C# are different languages. They have different rules for handling type promotion in the event of comparisons.

    In C++ and C, they're usually compared as if they were both unsigned. This is called "unsigned preserving". C++ and C compilers traditionally use "unsigned preserving" and the use of this is specified in the C++ standard and in K&R.

    In C#, they're both converted to signed longs and then compared. This is called "value preserving". C# specifies value preserving.

    ANSI C also specifies value preserving, but only when dealing with shorts and chars. Shorts and chars (signed and unsigned) are upconverted to ints in a value-preserving manner and then compared. So if an unsigned short were compared to a signed short, the result would come out like the C# example. Any time a conversion to a larger size is done, it's done in a value-preserving manner, but if the two variables are the same size (and not shorts or chars) and either one is unsigned, then they get compared as unsigned quantities in ANSI C. There's a good discussion of the up and down sides of both approaches in the comp.lang.c FAQ.

    0 讨论(0)
  • 2021-02-05 01:31

    I don't know about the standard of C#, but in the C++ standard, usual arithmetic conversions would be applied to both operands of relational operators:

    [......enum, floating point type involed......] 
    
    — Otherwise, the integral promotions (4.5) shall be performed on both operands.
      Then the following rules shall be applied to the promoted operands:
    
        — If both operands have the same type, no further conversion is needed.
    
        — Otherwise, if both operands have signed integer types or both have
          unsigned integer types, the operand with the type of lesser integer
          conversion rank shall be converted to the type of the operand with
          greater rank.
    
        — Otherwise, if the operand that has unsigned integer type has rank
          greater than or equal to the rank of the type of the other operand, the
          operand with signed integer type shall be converted to  the type of the
          operand with unsigned integer type.
    
        — Otherwise, if the type of the operand with signed integer type can
          represent all of the values of the type of the operand with unsigned
          integer type, the operand with unsigned integer type shall be converted
          to the type of the operand with signed integer type.
    
        — Otherwise, both operands shall be converted to the unsigned integer type 
          corresponding to the type of the operand with signed integer type.
    

    Thus, when unsigned int is compared with int, int would be converted to unsigned int, and -2 would become a very large number when converted to unsigned int.

    0 讨论(0)
提交回复
热议问题