开发者

Question about C datatype and constant

Greetings! I was experimenting with C language till I encountered something very strange. I was not able to explain myself the result shown below.

The Code:

#include <stdio.h>

int main(void)
{
    int num = 4294967295U;
    printf("%u\n", num);
    return 0;
}

The Question:

1.) As you see, I created an int which can hold numbers between -2147483648 to 2147483647.

2.) When I assign the value 4294967295 to this variable, the IDE shows me a warning message during compilation because the variable overflowed.

3.) Due to curiosity I added a U (unsigned) behind the nu开发者_如何学编程mber and when I recompiled it, the compiler did not return any warning message.

4.) I did further experiments by changing the U (unsigned) to L (long) and LL (long long). As expected, the warning message still persist for these two but not after I change it to UL (unsigned Long) and ULL (unsigned long long).

5.) Why is this happening?

The Warning Message :(For steps 2)

warning #2073: Overflow in converting constant expression from 'long long int' to 'int'.

The Warning Message:(For steps 4 LL & L)

warning #2073: Overflow in converting constant expression from 'long long int' to 'long int'.

And last, thanks for reading my question, your teachings and advices are much appreciated.


As per the ISO C99 standard, section 6.4.4.1 (Integer Constants), subsection Semantics, the type of an integer constant is the first type of the following table where the value can be represented:

                                    Octal or Hexadecimal
Suffix            Decimal Constant            Constant
none         int                    int
             long int               unsigned int
             long long int          long int
                                    unsigned long int
                                    long long int
                                    unsigned long long int

u or U       unsigned int           unsigned int
             unsigned long int      unsigned long int
             unsigned long long int unsigned long long int

l or L       long int               long int
             long long int          unsigned long int
                                    long long int
                                    unsigned long long int

both u or U  unsigned long int      unsigned long int
and l or L   unsigned long long int unsigned long long int

ll or LL     long long int          long long int
                                    unsigned long long int

both u or U  unsigned long long int unsigned long long int
and ll or LL

Particular implementations can have extended integer types that follow the same pattern as above.


Perhaps, by default, the compiler assumes you're typing in signed integers. When you give it 4294967295, that number doesn't fit into a 4-byte integer, so it uses an 8-byte integer to store it, instead. Then it has to do a lossy conversion (long long, AKA 8-byte, to long, AKA 4-byte), so it gives you a warning.

However, when you type 4294967295U, it knows you want an unsigned integer. That number fits into a 4-byte unsigned integer, so it has type long int, and no lossy conversion is necessary. (You're not losing data by going from unsigned long int to long int, just mis-representing it.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜