Implicit type promotion rules

后端 未结 2 782
隐瞒了意图╮
隐瞒了意图╮ 2020-11-21 06:49

This post is meant to be used as a FAQ regarding implicit integer promotion in C, particularly implicit promotion caused by the usual arithmetic conversions and/or the i

2条回答
  •  心在旅途
    2020-11-21 07:00

    According to the previous post, I want to give more information about each example.

    Example 1)

    int main(){
        unsigned char x = 0;
        unsigned char y = 1;
        printf("%u\n", x - y); 
        printf("%d\n", x - y);
    }
    

    Since unsigned char is smaller than int, we apply the integer promotion on them, then we have (int)x-(int)y = (int)(-1) and unsigned int (-1) = 4294967295.

    The output from the above code:(same as what we expected)

    4294967295
    -1
    

    How to fix it?

    I tried what the previous post recommanded, but it doesn't really work. Here is the code based on the previous post:

    change one of them to unsigned int

    int main(){
        unsigned int x = 0;
        unsigned char y = 1;
        printf("%u\n", x - y); 
        printf("%d\n", x - y);
    }
    

    Since x is already an unsigned integer, we only apply the integer promotion to y. Then we get (unsigned int)x-(int)y. Since they still don't have the same type, we apply the usual arithmetic converions, we get (unsigned int)x-(unsigned int)y = 4294967295.

    The output from the above code:(same as what we expected):

    4294967295
    -1
    

    Similarly, the following code gets the same result:

    int main(){
        unsigned char x = 0;
        unsigned int y = 1;
        printf("%u\n", x - y); 
        printf("%d\n", x - y);
    }
    

    change both of them to unsigned int

    int main(){
        unsigned int x = 0;
        unsigned int y = 1;
        printf("%u\n", x - y); 
        printf("%d\n", x - y);
    }
    

    Since both of them are unsigned int, no integer promotion is needed. By the usual arithmetic converison(have the same type), (unsigned int)x-(unsigned int)y = 4294967295.

    The output from the above code:(same as what we expected):

    4294967295
    -1
    

    One of possible ways to fix the code:(add a type cast in the end)

    int main(){
        unsigned char x = 0;
        unsigned char y = 1;
        printf("%u\n", x - y); 
        printf("%d\n", x - y);
        unsigned char z = x-y;
        printf("%u\n", z);
    }
    

    The output from the above code:

    4294967295
    -1
    255
    

    Example 2)

    int main(){
        unsigned int a = 1;
        signed int b = -2;
        if(a + b > 0)
            puts("-1 is larger than 0");
            printf("%u\n", a+b);
    }
    

    Since both of them are integers, no integer promotion is needed. By the usual arithmetic conversion, we get (unsigned int)a+(unsigned int)b = 1+4294967294 = 4294967295.

    The output from the above code:(same as what we expected)

    -1 is larger than 0
    4294967295
    

    How to fix it?

    int main(){
        unsigned int a = 1;
        signed int b = -2;
        signed int c = a+b;
        if(c < 0)
            puts("-1 is smaller than 0");
            printf("%d\n", c);
    }
    

    The output from the above code:

    -1 is smaller than 0
    -1
    

    Example 3)

    int main(){
        unsigned short a = 1;
        signed short b = -2;
        if(a + b < 0)
            puts("-1 is smaller than 0");
            printf("%d\n", a+b);
    }
    

    The last example fixed the problem since a and b both converted to int due to the integer promotion.

    The output from the above code:

    -1 is smaller than 0
    -1
    

    If I got some concepts mixed up, please let me know. Thanks~

提交回复
热议问题