C usual arithmetic conversions

前端 未结 4 931
攒了一身酷
攒了一身酷 2020-12-01 15:08

I was reading in the C99 standard about the usual arithmetic conversions.

If both operands have the same type, then no further conversion is needed.

4条回答
  •  青春惊慌失措
    2020-12-01 15:56

    Repeating the relevant portion of the code from the question:

    unsigned int a = 10;
    signed int b = -5;
    
    printf("%d\n", a + b); /* 5 */
    printf("%u\n", a + b); /* 5 */
    

    In a + b, b is converted to unsigned int, (yielding UINT_MAX + 1 - 5 by the rule for unsigned-to-signed conversion). The result of adding 10 to this value is 5, by the rules of unsigned arithmetic, and its type is unsigned int. In most cases, the type of a C expression is independent of the context in which it appears. (Note that none of this depends on the representation; conversion and arithmetic are defined purely in terms of numeric values.)

    For the second printf call, the result is straightforward: "%u" expects an argument of type unsigned int, and you've given it one. It prints "5\n".

    The first printf is a little more complicated. "%d" expects an argument of type int, but you're giving it an argument of type unsigned int. In most cases, a type mismatch like this results in undefined behavior, but there's a special-case rule that corresponding signed and unsigned types are interchangeable as function arguments -- as long as the value is representable in both types (as it is here). So the first printf also prints "5\n".

    Again, all this behavior is defined in terms of values, not representations (except for the requirement that a given value has the same representation in corresponding signed and unsigned types). You'd get the same result on a system where signed int and unsigned int are both 37 bits, signed int has 7 padding bits, unsigned int has 11 padding bits, and signed int uses a 1s'-complement or sign-and-magnitude representation. (No such system exists in real life, as far as I know.)

提交回复
热议问题