469,955 Members | 2,494 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

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

Integer promotion and overflow

Hi,
I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits
and long long ints are 64 bits.

When i have:

int num=9600;
long long int reg=(long long)800000000000/(5000000*num);

the denominator overflows and gives an incorrect answer: reg=1059
With an extra cast:

long long int reg=(long long)800000000000/((long long)5000000*num);

i get: reg=16
If the numerator is a long long int, should the denominator be
automatically promoted to a long long int?
Nov 14 '05 #1
20 2033
Russell Shaw wrote:
Hi,
I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits
and long long ints are 64 bits.

When i have:

int num=9600;
long long int reg=(long long)800000000000/(5000000*num);

the denominator overflows and gives an incorrect answer: reg=1059
With an extra cast:

long long int reg=(long long)800000000000/((long long)5000000*num);

i get: reg=16
If the numerator is a long long int, should the denominator be
automatically promoted to a long long int?


lcc-win32 gives the same answer as gcc. The problem is
that the denomitar *is* converted to long long. The
compiler does:

long long int reg=(long long)800000000000/(long long)(5000000*num);

Neither gcc nor lcc-win32 realize that the denominator is an
expression, converting each member to the highest rank type.

Maybe there are compilers that clever, but I would not rely
on it, and would add the cast.

jacob
Nov 14 '05 #2
Russell Shaw wrote:
Hi,
I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits
and long long ints are 64 bits.

When i have:

int num=9600;
long long int reg=(long long)800000000000/(5000000*num);

the denominator overflows and gives an incorrect answer: reg=1059
With an extra cast:

long long int reg=(long long)800000000000/((long long)5000000*num);

i get: reg=16
If the numerator is a long long int, should the denominator be
automatically promoted to a long long int?


Yes. But the denominator (in the first form) is itself
the product of two factors of type `int', so it is calculated
in `int' arithmetic. The product is too large for an `int',
so it overflows and is chopped down to 32 bits (on your system;
C itself doesn't guarantee what happens). Then the already-
damaged value is promoted to `long long' for the division, but
it's too late: the denominator is much smaller than intended,
so the quotient comes out much too large.

In the second form, the 5000000 term is converted to `long
long' by the cast operator. The denominator is then the product
of a `long long' and an `int', so `num' is converted to `long
long' and the multiplication is carried out in `long long'
arithmetic and does not overflow. Then the division takes
place, and everything comes out as expected.

A better way to write this would be to make the constants
`long long' to begin with:

long long int reg = 800000000000LL / (5000000LL * num);

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #3
On Sun, 02 Jan 2005 17:26:27 +0100, jacob navia
<ja***@jacob.remcomp.fr> wrote:
lcc-win32 gives the same answer as gcc. The problem is
that the denomitar *is* converted to long long. The
compiler does:

long long int reg=(long long)800000000000/(long long)(5000000*num);

Neither gcc nor lcc-win32 realize that the denominator is an
expression, converting each member to the highest rank type.
Nor should they, C is specified such that conversions occur only when
they are forced because the types are dissimilar (or when forced with a
cast). For instance:

long long denom = 5000000 * num;

will give the same overflow, because it is specified that 5000000*num is
calculated and only then converted to a long long.
Maybe there are compilers that clever, but I would not rely
on it, and would add the cast.


It would not be 'clever', it would be against the standard. There are
other /languages/ which have the semantics the other way round, so that
expression type is propagated left to right (Algol and Pascal, I
believe, do that), but any C compiler must do the sub-expressions first
and promote the types only when it is necessary because the other
operand is a higher type.

Chris C
Nov 14 '05 #4
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits
and long long ints are 64 bits.

When i have:

int num=9600;
long long int reg=(long long)800000000000/(5000000*num);

the denominator overflows and gives an incorrect answer: reg=1059

With an extra cast:

long long int reg=(long long)800000000000/((long long)5000000*num);

i get: reg=16

If the numerator is a long long int, should the denominator be
automatically promoted to a long long int?


The evaluation of an expression is not affected by the context in
which it appears. Think of expressions, including their
subexpressions, as being evaluated bottom-up, not top-down.

The right operand of the "/" operator is:

(5000000*num)

Each operand of the "*" is of type int, so it's an int-by-int
multiplication yielding an int result. (It overflows, which invokes
undefined behavior, which most likely shows up as discarding the
high-order bits.) That int result then becomes the right operand of
the "/" operator. The left operand of the "/" operator is (long
long)800000000000, which is of type long long, so the right operand is
promoted to long long -- but that promotion (to 64 bits) is done
*after* the 32-bit multiplication.

Since the overflow invokes undefined behavior, I suppose a
sufficiently clever compiler could let the context affect the
evaluation of (5000000*num), so the whole expression yields a
mathematically correct result. But such cleverness doesn't really do
you any favors, it merely masks your error.

(There are languages in which the context of an expression affects its
evaluation. C is not such a language.)

You might prefer to use a suffix on the integer constants rather than
casting them to long long:

long long int reg=800000000000LL/(5000000LL*num);

On the other hand, the cast uses the type name explicitly, so it might
be considered clearer.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #5
Chris Croughton <ch***@keristor.net> writes:
On Sun, 02 Jan 2005 17:26:27 +0100, jacob navia
<ja***@jacob.remcomp.fr> wrote:

[...]
Maybe there are compilers that clever, but I would not rely
on it, and would add the cast.


It would not be 'clever', it would be against the standard.

[...]

As I mentioned in another thread, it wouldn't be against the standard
if it affected the visible behavior of the program only when it
invokes undefined behavior. But such "cleverness" would not be a good
idea, since it would tend to mask errors.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #6
Keith Thompson <ks***@mib.org> writes:
Chris Croughton <ch***@keristor.net> writes:
On Sun, 02 Jan 2005 17:26:27 +0100, jacob navia
<ja***@jacob.remcomp.fr> wrote:

[...]
Maybe there are compilers that clever, but I would not rely
on it, and would add the cast.


It would not be 'clever', it would be against the standard.

[...]

As I mentioned in another thread, it wouldn't be against the standard
if it affected the visible behavior of the program only when it
invokes undefined behavior. But such "cleverness" would not be a good
idea, since it would tend to mask errors.


Sorry, I meant to say "As I mentioned elsewhere in this thread ...".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #7
On Sun, 02 Jan 2005 23:03:44 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
Chris Croughton <ch***@keristor.net> writes:
On Sun, 02 Jan 2005 17:26:27 +0100, jacob navia
<ja***@jacob.remcomp.fr> wrote:

[...]
Maybe there are compilers that clever, but I would not rely
on it, and would add the cast.


It would not be 'clever', it would be against the standard.

[...]

As I mentioned in another thread, it wouldn't be against the standard
if it affected the visible behavior of the program only when it
invokes undefined behavior. But such "cleverness" would not be a good
idea, since it would tend to mask errors.


True. But if either of the operands in the calculation of the
denominator were unsigned, such 'early promotion' would be
non-conforming.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
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
Nov 14 '05 #8
Neo

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits
and long long ints are 64 bits.

When i have:

int num=9600;
long long int reg=(long long)800000000000/(5000000*num);

the denominator overflows and gives an incorrect answer: reg=1059

With an extra cast:

long long int reg=(long long)800000000000/((long long)5000000*num);

i get: reg=16

If the numerator is a long long int, should the denominator be
automatically promoted to a long long int?
The evaluation of an expression is not affected by the context in
which it appears. Think of expressions, including their
subexpressions, as being evaluated bottom-up, not top-down.

The right operand of the "/" operator is:

(5000000*num)

Each operand of the "*" is of type int, so it's an int-by-int
multiplication yielding an int result. (It overflows, which invokes
undefined behavior, which most likely shows up as discarding the
high-order bits.) That int result then becomes the right operand of
the "/" operator. The left operand of the "/" operator is (long
long)800000000000, which is of type long long, so the right operand is
promoted to long long -- but that promotion (to 64 bits) is done
*after* the 32-bit multiplication.

Since the overflow invokes undefined behavior, I suppose a
sufficiently clever compiler could let the context affect the
evaluation of (5000000*num), so the whole expression yields a
mathematically correct result. But such cleverness doesn't really do
you any favors, it merely masks your error.

(There are languages in which the context of an expression affects its
evaluation. C is not such a language.)

You might prefer to use a suffix on the integer constants rather than
casting them to long long:

long long int reg=800000000000LL/(5000000LL*num);


Hi Keith,

I used the following form :

int num = 9600;
long long int i = (long long)800000000000/(5000000LL * num);
printf("%ld\n", i);

on my Win XP machine (gcc 3.3.1) gcc flash out the following warning :
longlong.c: In function `main':
longlong.c:7: warning: integer constant is too large for "long" type
output : 16

and to more surprise when compiling the same code on Solaris Workstation
with gcc 3.3 warning was the same as above but the result :
output : 0

WHY IT IS SO??????

Thanks n Regards
-Neo

On the other hand, the cast uses the type name explicitly, so it might
be considered clearer.

--
Keith Thompson (The_Other_Keith) ks***@mib.org
<http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*>
<http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Nov 14 '05 #9


Neo wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits
and long long ints are 64 bits.

When i have:

int num=9600;
long long int reg=(long long)800000000000/(5000000*num);

the denominator overflows and gives an incorrect answer: reg=1059

With an extra cast:

long long int reg=(long long)800000000000/((long long)5000000*num);

i get: reg=16

If the numerator is a long long int, should the denominator be
automatically promoted to a long long int?


The evaluation of an expression is not affected by the context in
which it appears. Think of expressions, including their
subexpressions, as being evaluated bottom-up, not top-down.

The right operand of the "/" operator is:

(5000000*num)

Each operand of the "*" is of type int, so it's an int-by-int
multiplication yielding an int result. (It overflows, which invokes
undefined behavior, which most likely shows up as discarding the
high-order bits.) That int result then becomes the right operand of
the "/" operator. The left operand of the "/" operator is (long
long)800000000000, which is of type long long, so the right operand is
promoted to long long -- but that promotion (to 64 bits) is done
*after* the 32-bit multiplication.

Since the overflow invokes undefined behavior, I suppose a
sufficiently clever compiler could let the context affect the
evaluation of (5000000*num), so the whole expression yields a
mathematically correct result. But such cleverness doesn't really do
you any favors, it merely masks your error.

(There are languages in which the context of an expression affects its
evaluation. C is not such a language.)

You might prefer to use a suffix on the integer constants rather than
casting them to long long:

long long int reg=800000000000LL/(5000000LL*num);

Hi Keith,

I used the following form :

int num = 9600;
long long int i = (long long)800000000000/(5000000LL * num);
printf("%ld\n", i);

on my Win XP machine (gcc 3.3.1) gcc flash out the following warning :
longlong.c: In function `main':
longlong.c:7: warning: integer constant is too large for "long" type
output : 16

and to more surprise when compiling the same code on Solaris Workstation
with gcc 3.3 warning was the same as above but the result :
output : 0

WHY IT IS SO??????


RTFmanpage (printf):

The length modifier l specifies _long_, not _long_long_.
If you want to print a long long, use ll:
printf("%lld\n", i);

Depending on the byte representation of the number in memory, we may
well arrive at 16 (korrekt) or 0, if erroneously reading only a part
of the bytes belonging to the argument.
Cheers
Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #10
Jack Klein <ja*******@spamcop.net> writes:
On Sun, 02 Jan 2005 23:03:44 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
Chris Croughton <ch***@keristor.net> writes:
> On Sun, 02 Jan 2005 17:26:27 +0100, jacob navia
> <ja***@jacob.remcomp.fr> wrote:

[...]
>> Maybe there are compilers that clever, but I would not rely
>> on it, and would add the cast.
>
> It would not be 'clever', it would be against the standard.

[...]

As I mentioned in another thread, it wouldn't be against the standard [correction: elsewhere in this thread] if it affected the visible behavior of the program only when it
invokes undefined behavior. But such "cleverness" would not be a good
idea, since it would tend to mask errors.


True. But if either of the operands in the calculation of the
denominator were unsigned, such 'early promotion' would be
non-conforming.


Agreed (because unsigned overflow doesn't invoke undefined behavior
(which you know, of course, but others reading this may not)).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #11
Neo

"Michael Mair" <Mi**********@invalid.invalid> wrote in message
news:33*************@individual.net...


Neo wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:

I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits
and long long ints are 64 bits.

When i have:

int num=9600;
long long int reg=(long long)800000000000/(5000000*num);

the denominator overflows and gives an incorrect answer: reg=1059

With an extra cast:

long long int reg=(long long)800000000000/((long long)5000000*num);

i get: reg=16

If the numerator is a long long int, should the denominator be
automatically promoted to a long long int?

The evaluation of an expression is not affected by the context in
which it appears. Think of expressions, including their
subexpressions, as being evaluated bottom-up, not top-down.

The right operand of the "/" operator is:

(5000000*num)

Each operand of the "*" is of type int, so it's an int-by-int
multiplication yielding an int result. (It overflows, which invokes
undefined behavior, which most likely shows up as discarding the
high-order bits.) That int result then becomes the right operand of
the "/" operator. The left operand of the "/" operator is (long
long)800000000000, which is of type long long, so the right operand is
promoted to long long -- but that promotion (to 64 bits) is done
*after* the 32-bit multiplication.

Since the overflow invokes undefined behavior, I suppose a
sufficiently clever compiler could let the context affect the
evaluation of (5000000*num), so the whole expression yields a
mathematically correct result. But such cleverness doesn't really do
you any favors, it merely masks your error.

(There are languages in which the context of an expression affects its
evaluation. C is not such a language.)

You might prefer to use a suffix on the integer constants rather than
casting them to long long:

long long int reg=800000000000LL/(5000000LL*num);

Hi Keith,

I used the following form :

int num = 9600;
long long int i = (long long)800000000000/(5000000LL * num);
printf("%ld\n", i);

on my Win XP machine (gcc 3.3.1) gcc flash out the following warning :
longlong.c: In function `main':
longlong.c:7: warning: integer constant is too large for "long" type
output : 16

and to more surprise when compiling the same code on Solaris Workstation
with gcc 3.3 warning was the same as above but the result :
output : 0

WHY IT IS SO??????


RTFmanpage (printf):

The length modifier l specifies _long_, not _long_long_.
If you want to print a long long, use ll:
printf("%lld\n", i);

Depending on the byte representation of the number in memory, we may
well arrive at 16 (korrekt) or 0, if erroneously reading only a part
of the bytes belonging to the argument.


Michael, thanks for the correction. It should be obviously "%lld\n".
But why the warning??? its still there.


Cheers
Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #12
"Neo" <ti***************@yahoo.com> writes:
[...]
I used the following form :

int num = 9600;
long long int i = (long long)800000000000/(5000000LL * num);
printf("%ld\n", i);

on my Win XP machine (gcc 3.3.1) gcc flash out the following warning :
longlong.c: In function `main':
longlong.c:7: warning: integer constant is too large for "long" type
output : 16
In C99, the type of an unsuffixed decimal integer constant is the
first of int, long int, or long long int in which its value can be
represented.

In C90, there is no type long long int, so the constant is of type
long int (which is too small).

I think gcc is acting as a C90 compiler as far as determining the
types of integer constants is concerned, but is supporting long long
as an extension.

Try invoking gcc with "-std=c99" and/or use 800000000000LL rather than
(long long)800000000000.
and to more surprise when compiling the same code on Solaris Workstation
with gcc 3.3 warning was the same as above but the result :
output : 0


Because you're trying to print a long long value, but you're telling
printf to expect a long ("%ld"). Use "%lld" to print a long long.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #13

Eric Sosman wrote:
Russell Shaw wrote:
Hi,
I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits and long long ints are 64 bits.

When i have:

int num=9600;
long long int reg=(long long)800000000000/(5000000*num);

the denominator overflows and gives an incorrect answer: reg=1059
With an extra cast:

long long int reg=(long long)800000000000/((long long)5000000*num);
i get: reg=16
If the numerator is a long long int, should the denominator be
automatically promoted to a long long int?


Yes. But the denominator (in the first form) is itself
the product of two factors of type `int', so it is calculated
in `int' arithmetic.


It would seem that 6.4.4.1#5 says that if 5000000 cannot be
represented by the type int then it would try long int
and if not long int, then long long int.

"The type of an integer constant is the first of the
corresponding list in which its value can be represented."

Atleast, that is how I interpreted it. The table follows with

Suffix Decimal Constant
none int
long int
long long int
hopefully google does not ruin my formatting

--
aegis

Nov 14 '05 #14
Neo wrote:
"Michael Mair" <Mi**********@invalid.invalid> wrote in message
news:33*************@individual.net...

Neo wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...

....
Hi Keith,

I used the following form :

int num = 9600;
long long int i = (long long)800000000000/(5000000LL * num);
printf("%ld\n", i);

on my Win XP machine (gcc 3.3.1) gcc flash out the following warning :
longlong.c: In function `main':
longlong.c:7: warning: integer constant is too large for "long" type
output : 16

and to more surprise when compiling the same code on Solaris Workstation
with gcc 3.3 warning was the same as above but the result :
output : 0

WHY IT IS SO??????


RTFmanpage (printf):

The length modifier l specifies _long_, not _long_long_.
If you want to print a long long, use ll:
printf("%lld\n", i);

Depending on the byte representation of the number in memory, we may
well arrive at 16 (korrekt) or 0, if erroneously reading only a part
of the bytes belonging to the argument.

Michael, thanks for the correction. It should be obviously "%lld\n".
But why the warning??? its still there.


I get that warning in gcc-3.4.3 on linux too.
Nov 14 '05 #15


Neo wrote:
"Michael Mair" <Mi**********@invalid.invalid> wrote in message
news:33*************@individual.net...

Neo wrote:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
>I'm using gcc-3.4.3 on a linux pc. The ints and long ints are 32 bits
>and long long ints are 64 bits.
>
>When i have:
>
> int num=9600;
> long long int reg=(long long)800000000000/(5000000*num);
>
>the denominator overflows and gives an incorrect answer: reg=1059
>
>With an extra cast:
>
> long long int reg=(long long)800000000000/((long long)5000000*num);
>
>i get: reg=16
>
>If the numerator is a long long int, should the denominator be
>automatically promoted to a long long int?

The evaluation of an expression is not affected by the context in
which it appears. Think of expressions, including their
subexpressions, as being evaluated bottom-up, not top-down.

The right operand of the "/" operator is:

(5000000*num)

Each operand of the "*" is of type int, so it's an int-by-int
multiplication yielding an int result. (It overflows, which invokes
undefined behavior, which most likely shows up as discarding the
high-order bits.) That int result then becomes the right operand of
the "/" operator. The left operand of the "/" operator is (long
long)800000000000, which is of type long long, so the right operand is
promoted to long long -- but that promotion (to 64 bits) is done
*after* the 32-bit multiplication.

Since the overflow invokes undefined behavior, I suppose a
sufficiently clever compiler could let the context affect the
evaluation of (5000000*num), so the whole expression yields a
mathematically correct result. But such cleverness doesn't really do
you any favors, it merely masks your error.

(There are languages in which the context of an expression affects its
evaluation. C is not such a language.)

You might prefer to use a suffix on the integer constants rather than
casting them to long long:

long long int reg=800000000000LL/(5000000LL*num);
Hi Keith,

I used the following form :

int num = 9600;
long long int i = (long long)800000000000/(5000000LL * num);
printf("%ld\n", i);

on my Win XP machine (gcc 3.3.1) gcc flash out the following warning :
longlong.c: In function `main':
longlong.c:7: warning: integer constant is too large for "long" type
output : 16

and to more surprise when compiling the same code on Solaris Workstation
with gcc 3.3 warning was the same as above but the result :
output : 0

WHY IT IS SO??????


RTFmanpage (printf):

The length modifier l specifies _long_, not _long_long_.
If you want to print a long long, use ll:
printf("%lld\n", i);

Depending on the byte representation of the number in memory, we may
well arrive at 16 (korrekt) or 0, if erroneously reading only a part
of the bytes belonging to the argument.


Michael, thanks for the correction. It should be obviously "%lld\n".
But why the warning??? its still there.


I do not know which is "line 7", so I can only guess.
Probably, you do not invoke gcc in C99 mode -- C89/90 does not
know the type long long.
Please post your complete code or try what the compiler does for
gcc -Wall -O -std=c99 -pedantic
Cheers
Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #16
Neo

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
"Neo" <ti***************@yahoo.com> writes:
[...]
I used the following form :

int num = 9600;
long long int i = (long long)800000000000/(5000000LL * num);
printf("%ld\n", i);

on my Win XP machine (gcc 3.3.1) gcc flash out the following warning :
longlong.c: In function `main':
longlong.c:7: warning: integer constant is too large for "long" type
output : 16
In C99, the type of an unsuffixed decimal integer constant is the
first of int, long int, or long long int in which its value can be
represented.

In C90, there is no type long long int, so the constant is of type
long int (which is too small).

I think gcc is acting as a C90 compiler as far as determining the
types of integer constants is concerned, but is supporting long long
as an extension.

Try invoking gcc with "-std=c99" and/or use 800000000000LL rather than
(long long)800000000000.


yeah! thnx.
-Neo
and to more surprise when compiling the same code on Solaris Workstation
with gcc 3.3 warning was the same as above but the result :
output : 0


Because you're trying to print a long long value, but you're telling
printf to expect a long ("%ld"). Use "%lld" to print a long long.

--
Keith Thompson (The_Other_Keith) ks***@mib.org
<http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*>
<http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Nov 14 '05 #17
"aegis" <ae***@mad.scientist.com> writes:
Eric Sosman wrote:
Russell Shaw wrote: [...]
> If the numerator is a long long int, should the denominator be
> automatically promoted to a long long int?


Yes. But the denominator (in the first form) is itself
the product of two factors of type `int', so it is calculated
in `int' arithmetic.


It would seem that 6.4.4.1#5 says that if 5000000 cannot be
represented by the type int then it would try long int
and if not long int, then long long int.

"The type of an integer constant is the first of the
corresponding list in which its value can be represented."


On the system in question, int and long are both 32 bits, and long
long is 64 bits. Since 5000000 fits in 32 bits, it's of type int.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #18
is my interpretation correct though?

for example,

long long foo = 5000000000;

if 5000000000 cannot be represented by the type int
then the compiler sees if it can be represented by type long int
and if not, then it tries long long int.

I tried this with gcc invoking -std=c99 and it seems to initialize
to the correct value but issues a warning. Should it issue
the warning? If my interpretation is correct then I do not see how this
warrants a diagnostic.

--
aegis

Nov 14 '05 #19
aegis wrote:

is my interpretation correct though?

for example,

long long foo = 5000000000;

if 5000000000 cannot be represented by the type int
then the compiler sees if it can be represented by type long int
and if not, then it tries long long int.

I tried this with gcc invoking -std=c99 and it seems to initialize
to the correct value but issues a warning. Should it issue
the warning? If my interpretation is correct then I do not see how this
warrants a diagnostic.


Conforming C compilers can issue diagnostics for any circumstance
they like. They are /required/ to issue at least one diagnostic
if the translation unit contains any syntax errors or constraint
violations, but the Standard does not stop them issuing diagnostics
in other circumstances. For example, it's perfectly legal for
your compiler to diagnose:

int main(void)
{
return 0;
}

like this:

"Fatal error - missing environment division. Format your hard disk."

This diagnostic is utterly misleading, but perfectly legal. Such a
compiler wouldn't sell very well, but that's a completely different
kettle of fish.
Nov 14 '05 #20
"aegis" <ae***@mad.scientist.com> writes:
is my interpretation correct though?

for example,

long long foo = 5000000000;

if 5000000000 cannot be represented by the type int
then the compiler sees if it can be represented by type long int
and if not, then it tries long long int.

I tried this with gcc invoking -std=c99 and it seems to initialize
to the correct value but issues a warning. Should it issue
the warning? If my interpretation is correct then I do not see how this
warrants a diagnostic.


I wouldn't expect a warning in that case, but as infobahn points out
the standard allows a compiler to issue any diagnostic it likes.

You don't tell us what the warning is, so it's impossible to tell
what's going on. I tried compiling the above with several versions of
gcc. More recent versions give a warning

tmp.c:1: warning: integer constant is too large for "long" type

without "-std=c99"; none that I tried give a warning with "-std=c99".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

112 posts views Thread by Carsten Hansen | last post: by
3 posts views Thread by shmartonak | last post: by
21 posts views Thread by Frederick Gotham | last post: by
4 posts views Thread by spibou | last post: by
6 posts views Thread by sarathy | last post: by
2 posts views Thread by Sune | 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.