unsigned

Kaz Kylheku kaz@zeugmasystems.com
Tue Dec 5 19:25:00 GMT 2006


 Trevis Rothwell wrote:
> Given the following program:
> 
>   int main()
>   {
>     unsigned int squiggy = 2147483648;
>   }
> 
> Compliing on GCC 3.2.3, I get the following warning:
> 
>   $ gcc foo.c
>   foo.c: In function `main':
>   foo.c:3: warning: decimal constant is so large that it is unsigned
> 
> To the best of my knowledge, 2147483648 should fit with ample room to
> spare in an unsigned (4-byte) integer.

Ample room to spare? How so? It requires all 32 bits.  There is ample
/range/ to spare, maybe. :)

> What's going on?

The warning has nothing to do with the unsigned declaration. The
compiler simply isn't smart enough to realize that you are assigning the
constant to a type which can hold its value. The diagnostic is just
about the constant, independently of how it is used.

In C90 (let's ignore C99 and long long), an integer constant which does
not have any suffix (U or L) is given a type according these rules:

- if its value fits into int, then it is int
- otherwise if its value fits into unsigned int, then that's the type,
- otherwise long,
- then unsigned long.

You have written a constant which doesn't fit into int and must be made
into unsigned int, and the compiler is warning about that, that is all.
Try 2147483648U.

In C99 the rules have changed. A decimal integer constant is assigned
the first of these types that can represent its value:

- int
- long
- long long

The unsigned types are not considered. So that explains the reasoning
behind the new warning found in gcc 4.1.1.

In C99, only octal and hexadecimal constants (without the U suffix) have
the behavior that their type can be chosen from among the signed and
unsigned types. An unsuffixed hex or octal constant is assigned the
first one from this list:

- int
- unsigned int
- long
- unsigned long
- long long
- unsigned long long



More information about the Gcc-help mailing list