469,593 Members | 1,987 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,593 developers. It's quick & easy.

Integer overflow in expression

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

but when I use this

int main() {
unsigned long x = 0xC0000000; /* 3GB */
printf(" %x ", x);
}

It doesn't give out any errors. Any idea as to why its warning about
integer overflow when it is well within the range of 32bits ? My gcc
-v

Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 3.3.3 [FreeBSD] 20031106

Vivek
Nov 14 '05 #1
7 16607

"Vivek Mohan" <vi****@phreaker.net> wrote in message

unsigned long x = 3*1024*1024*1024; /* 3GB error*/
unsigned long x = 0xC0000000; /* 3GB OK*/

The compiler treats raw decimal integers as signed ints by default.If you
tag an "lu" on the end it will be OK.
Nov 14 '05 #2
Vivek Mohan wrote:

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
The compiler considers the constants 3 and 1024 to be of type int. So
the result of the multiplication expression (3*1024*1024*1024) is also
int. But the result is too large to be represented as an int, so the
compiler complains of integer overflow.

You need to arrange things so that the result of the expression is an
unsigned long. Simply assigning the result to an unsigned long variable
won't do it. You should force the compiler to treat each operand in the
expression as an unsigned long, like this:

unsigned long x = 3ul * 1024ul * 1024ul * 1024ul;

Two other things: you forget to #include <stdio.h> (for printf), and the
conversion specifier in the printf statement should be %lx, not %x,
because x is an unsigned long.
but when I use this

int main() {
unsigned long x = 0xC0000000; /* 3GB */
printf(" %x ", x);
}

It doesn't give out any errors.


The compiler sees that the constant 0xC0000000 can't be represented as
an int, so it regards it as some other type--maybe unsigned long.

--
Russell Hanneken
rg********@pobox.com
Remove the 'g' from my address to send me mail.
Nov 14 '05 #3
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" and "1024" are both integers so you're calculating using integer
math. Specify one/both as a long constant.
Nov 14 '05 #4
In article <41**************************@posting.google.com >, 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 (signed) * 1024 (signed) * 1024 (signed) * 1024 (signed)
[-] but when I use this

int main() {
unsigned long x = 0xC0000000; /* 3GB */
printf(" %x ", x);
} [-]
Or this ...
3 * 1024 * 1024 * 1024u
.... or this ...
3u * 1024 * 1024 * 1024
.... or ...
It doesn't give out any errors.

[-]

Cheers,
Juergen

--
\ Real name : Juergen Heinzl \ no flames /
\ Email private : ju*****@manannan.org \ send money instead /
\ Photo gallery : www.manannan.org \ /
Nov 14 '05 #5
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
Nov 14 '05 #6
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,
You should get more.
In function `main':
:4: warning: integer overflow in expression


The expression on the right of the equal sign has no longs (not to
mention unsigned longs), so is computed as an int. Try this fixed
version of your code:

#include <stdio.h> /* mha: fixed omitted header, providing
prototype required for variatic
function printf */
int main()
{
unsigned long x = 3ul * 1024 * 1024 * 1024; /* mha: fixed
initializer */
printf(" %lx\n", x); /* mha: fixed wrong specifier; fixed
implementation-specic behavior for
last output line not terminated with
an end-of-line character */
return 0; /* mha: added for the almost 100% of
people with C89, not C99 compilers */
}

Nov 14 '05 #7
Russell Hanneken <rg********@pobox.com> wrote:
Vivek Mohan wrote:
int main() {
unsigned long x = 3*1024*1024*1024; /* 3GB */
printf(" %x ", x);
}
You need to arrange things so that the result of the expression is an
unsigned long. Simply assigning the result to an unsigned long variable
won't do it.
The reason for this, BTW, is that by the time the assignment is done,
the computation has already been performed using ints.
You should force the compiler to treat each operand in the
expression as an unsigned long, like this:

unsigned long x = 3ul * 1024ul * 1024ul * 1024ul;


No need. All you need is to force it to consider the first operand to be
an unsigned long; automatic promotions will ensure that the rest will be
promoted before being multiplied.

Richard
Nov 14 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

20 posts views Thread by Russell Shaw | last post: by
25 posts views Thread by bruce.james.lee | last post: by
25 posts views Thread by junky_fellow | last post: by
33 posts views Thread by dragoncoder | last post: by
40 posts views Thread by Robert Seacord | last post: by
13 posts views Thread by Freaker85 | last post: by
232 posts views Thread by robert maas, see http://tinyurl.com/uh3t | last post: by
42 posts views Thread by thomas.mertes | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.