On Wed, 29 Mar 2006 17:26:08 +0200, fctk <-> wrote in comp.lang.c:
[color=blue]
> hello,
>
> i'm trying to compile this small program:
>
> int main(void) {
>
> unsigned long int max;
>
> max = 4000000000;
>
> return 0;
>
> }
>
> but i get the following warning, and can't understand why:
>
> limits.c: In function `main':
> limits.c:5: warning: this decimal constant is unsigned only in ISO C90[/color]
That's because the rules changed in 1999.
[color=blue]
> i read both here
> (
http://www-ccs.ucsd.edu/c/express.ht...ger%20constant)
> and on my book (Kelley-Pohl), that if i have a decimal integer constant
> with no suffix, then the compiler will choose among the following
> ordered list:
>
> 1) int
> 2) long int
> 3) unsigned long int
>
> the first one which is able to represent that constant. since on my
> system both int and long int are 4 bytes sized, then i would expect
> 4000000000 is unsigned long int. since i am assigning an unsigned long
> int constant to an unsigned long int variable, i don't see why i should
> get that warning.[/color]
That's because the rules changed in 1999. If your compiler uses the
C99 rules, an unadorned decimal constant is the first one of:
-- signed int
-- signed long
-- signed long long
....in which it fits. Under C99, an unadorned decimal constant never
becomes an unsigned type.
So the diagnostic is telling you that the constant is interpreted
differently depending on which version of ISO C is being conformed to.
If the compiler is invoked in C90 conforming mode, the type of the
constant is "unsigned long", but in C99 conforming mode, the type is
"signed long long". If the destination was a signed type, the actual
value after initialization might be different between the two
versions. And this code could break on other platforms.
[color=blue]
> i know two ways to avoid the warning:
>
> 1) specifing 4000000000UL instead of 4000000000
> 2) using 0xEE6B2800 instead of 4000000000
>
> but i'd like to understand why 4000000000 is not ok.[/color]
Nobody says that it isn't "OK". A compiler is allowed to issue a
diagnostic about anything for any reason, as long as it issues those
required by the standard.
[color=blue]
> note that i'd like to write only ANSI/ISO C compatible programs
> (C89/C90), no traditional C or C99 ones (after having learned C89, i
> will switch to C99 if i'll have time).[/color]
Then follow the MISRA rule (one of the good ones) about always
specifying a type for numeric literals.
[color=blue]
> i am using gcc version 3.4.4 on a gentoo linux system.
> parameters: gcc -x c -ansi -pedantic -Wall -Wextra (i get that warning
> also with no parameters at all)[/color]
IIRC, 3.x versions of gcc had some C99 features included, and they,
and even earlier versions, of gcc supported the "long long" int types
as an extension to C90.
[color=blue]
> also, i found this parameter:
>
> -Wtraditional
>
> [...]
>
> * The ISO type of an integer constant has a different width or
> signedness from its traditional type. This warning is only issued if
> the base of the constant is ten. I.e. hexadecimal or octal values,
> which typically represent bit patterns, are not warned about.
>
> [...]
>
> anyway, even if i put -Wno-traditional, i always get that warning.[/color]
The real answer is "don't do this". Specify the exact type of your
literal with a suffix, for maximum portability under any version of
the C standard.
Also consult your compiler documentation. There is some way to tell
gcc which version of the C standard you want it to conform to.
--
Jack Klein
Home:
http://JK-Technology.Com
FAQs for
comp.lang.c
http://c-faq.com/
comp.lang.c++
http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html