Vivek Mohan wrote:
Hi,
I am using gcc, and I am a bit confused about the warning message I
got when I compiled and ran this small code snippet -
int main() {
unsigned long x = 3*1024*1024*1024; /* 3GB */
printf(" %x ", x);
}
I got the following error,
In function `main':
:4: warning: integer overflow in expression
`3' is a signed int, and so are all three appearances
of `1024'. You have asked for these four signed ints to
be multiplied together, producing a product that is also
a signed int, and then for that signed int product to be
converted to unsigned long. The compiler is telling you
that the product is too large to fit in a signed int.
Here's a fix:
unsigned long x = 3u * 1024u * 1024u * 1024u;
Now all the operands are unsigned ints, and the product
is also an unsigned int. The product will not overflow a
32-bit unsigned int, so all will be well.
... maybe. It appears that your compiler uses 32 bits
for an int, but not all compilers do so. The C language
guarantees that an int has at least 16 bits, but does not
require it to be wider. If int (and hence unsigned int)
are 16 bits wide (or 18, or 24, or anything less than 32),
the product will not be "3GB" as you expect.
Here's a better fix:
unsigned long x = 3ul * 1024ul * 1024ul * 1024ul;
This time, all the operands are unsigned longs. In all C
implementations, long and unsigned long are at least 32
bits wide, possibly wider. That means that your calculation
will now behave as you intended, regardless of the platform.
By the way, you should use "%lx" rather than just "%x"
to print the value; the 'l' tells printf() that the operand
is "long" instead of "plain." You mention that you're using
gcc; if you run it as "gcc -Wall -W" it will catch this error
for you. (In my own work, I also add "-ansi -pedantic" for
all modules that can tolerate it; some system-dependent
modules cannot.)
--
Er*********@sun.com