By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,611 Members | 1,635 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,611 IT Pros & Developers. It's quick & easy.

cout << -2147483648 ; strange output in g++

P: n/a
Hi,

For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)

cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;

The outputs I get are:
2147483648
-2147483648,2147483647

with this compile time warning: this decimal constant is unsigned only
in ISO C90

I am surprised why the negative number is printed as positive.

Could you please explain why this behaviour?

thanks
suresh
Jan 2 '08 #1
Share this Question
Share on Google+
46 Replies


P: n/a
suresh wrote:
For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)

cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;

The outputs I get are:
2147483648
-2147483648,2147483647

with this compile time warning: this decimal constant is unsigned only
in ISO C90

I am surprised why the negative number is printed as positive.

Could you please explain why this behaviour?
The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'. If your system's 'long' has the same size
as 'int' (like on Windows, for example), the behaviour is undefined.

Try adding the suffix 'U' to the literal.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jan 2 '08 #2

P: n/a
suresh wrote:
Hi,

For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)

cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;

The outputs I get are:
2147483648
-2147483648,2147483647

with this compile time warning: this decimal constant is unsigned only
in ISO C90

I am surprised why the negative number is printed as positive.

Could you please explain why this behaviour?
The range for a 32 bit signed number using 2's complement is -2147483647 to
2147483648. -2147483648 does not fit in a signed 32 bit int. On a 32 bit
compiler, a 32 bit number may be the largest. Since -2147483648 does not
fit in a signed 32 bit int, it seems it is converting it to an unsigned 32
bit int.

Basically, the number you are trying to represent doesn't fit in an int
variable. I believe this is giving you an undefined value.

--
Jim Langston
ta*******@rocketmail.com
Jan 2 '08 #3

P: n/a
HI Victor,

Could you be little bit more elaborative? The max value of int in my
linux machine is 2147483648. Then why did you say that The literal
'2147483648' does not fit in an int?

long has the same size as int on my machine too.

suresh
The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'. If your system's 'long' has the same size
as 'int' (like on Windows, for example), the behaviour is undefined.

Try adding the suffix 'U' to the literal.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jan 2 '08 #4

P: n/a
Victor Bazarov wrote:
suresh wrote:
>For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)

cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;

The outputs I get are:
2147483648
-2147483648,2147483647

with this compile time warning: this decimal constant is unsigned only
in ISO C90

I am surprised why the negative number is printed as positive.

Could you please explain why this behaviour?

The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'.
My compiler promoted it to unsigned long.
If your system's 'long' has the same size as 'int' (like on Windows, for
example), the behaviour is undefined.

Try adding the suffix 'U' to the literal.
How would that help? Or did you miss that the OP actually wanted to print a
negative int value?

Jan 2 '08 #5

P: n/a
Hi Jim Langston,

As I understand, the range of 32 bit signed number is -2147483648 to
2147483647. So it should work correctly.

Again, the code snippet,

signed int x = -2147483648;
cout << x << endl;

works correctly though the warning "this decimal constant is unsigned
only in ISO C90" is produced.

suresh.
>
The range for a 32 bit signed number using 2's complement is -2147483647 to
2147483648. -2147483648 does not fit in a signed 32 bit int. On a 32 bit
compiler, a 32 bit number may be the largest. Since -2147483648 does not
fit in a signed 32 bit int, it seems it is converting it to an unsigned 32
bit int.

Basically, the number you are trying to represent doesn't fit in an int
variable. I believe this is giving you an undefined value.

--
Jim Langston
tazmas...@rocketmail.com
Jan 2 '08 #6

P: n/a
I just want to know why this funny behavior is happening...
How would that help? Or did you miss that the OP actually wanted to print a
negative int value?
Jan 2 '08 #7

P: n/a
suresh wrote:
Hi Jim Langston,

As I understand, the range of 32 bit signed number is -2147483648 to
2147483647. So it should work correctly.

Again, the code snippet,

signed int x = -2147483648;
cout << x << endl;

works correctly though the warning "this decimal constant is unsigned
only in ISO C90" is produced.

suresh.
>>
The range for a 32 bit signed number using 2's complement is
-2147483647 to 2147483648. -2147483648 does not fit in a signed 32
bit int. On a 32 bit compiler, a 32 bit number may be the largest.
Since -2147483648 does not fit in a signed 32 bit int, it seems it
is converting it to an unsigned 32 bit int.

Basically, the number you are trying to represent doesn't fit in an
int variable. I believe this is giving you an undefined value.
Undefined. Undefined means it may work as expected, or not. Which is what
you're running into. Just because it gives you output you expect at one
point and not an other doesn't meat it's always going to work that way.

Trying to define undefined behavior is like trying to herd cats.

--
Jim Langston
ta*******@rocketmail.com
Jan 2 '08 #8

P: n/a
My question is different. An integer can really take the value
-2147483648. Then why undefined behaviour etc?

suresh
Undefined. Undefined means it may work as expected, or not. Which is what
you're running into. Just because it gives you output you expect at one
point and not an other doesn't meat it's always going to work that way.

Trying to define undefined behavior is like trying to herd cats.

--
Jim Langston
tazmas...@rocketmail.com
Jan 2 '08 #9

P: n/a
suresh wrote:
:: Hi,
::
:: For this code snippet, I get the following output, which I am
:: unable to understand.
:: (2^31 = 2147483648)
::
:: cout<< -2147483648 << endl;
:: cout << numeric_limits<int>::min() <<',' <<
:: numeric_limits<int>::max()<< endl;
::
:: The outputs I get are:
:: 2147483648
:: -2147483648,2147483647
::
:: with this compile time warning: this decimal constant is unsigned
:: only in ISO C90
::
:: I am surprised why the negative number is printed as positive.
::
:: Could you please explain why this behaviour?
::

Your value -2147483648 actually has two parts, 2147483648 and a minus
sign. The problem is that 2147483648 is too large to fit in an int, so
you really need a larger type to store it. If you don't have that,
you're in trouble!

If you look in the limits.h header (or <climits>), I bet the value for
INT_MIN is written something like

#define INT_MIN (-2147483647 - 1)

to avoid this overflow.

Bo Persson
Jan 2 '08 #10

P: n/a
Hi Bo Persson,

Thanks for the wonderful answer. But then why did it work correctly in
this way?

int x = -2147483648;
cout << x << endl;
//why the two parts thing you said is not applying here?
suresh

On Jan 2, 9:38 pm, "Bo Persson" <b...@gmb.dkwrote:
Your value -2147483648 actually has two parts, 2147483648 and a minus
sign. The problem is that 2147483648 is too large to fit in an int, so
you really need a larger type to store it. If you don't have that,
you're in trouble!

If you look in the limits.h header (or <climits>), I bet the value for
INT_MIN is written something like

#define INT_MIN (-2147483647 - 1)

to avoid this overflow.

Bo Persson
Jan 2 '08 #11

P: n/a
On 2 ÑÎ×, 21:00, suresh <suresh.amritap...@gmail.comwrote:
Hi,

For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)

šcout<< š-2147483648 << endl;
š cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;

The outputs I get are:
2147483648
-2147483648,2147483647

with this compile time warning: this decimal constant is unsigned only
in ISO C90

I am surprised why the negative number is printed as positive.

Could you please explain why this behaviour?

thanks
suresh
I'm not too invilved with this but i'll try to guess.

First lets parse compiler warning message. `only' refers to the
phrase before it, so we're guessing that in C90 standard that you're
obviously compiling against this constant can be unsigned only.

Second, how a constant with minus sign can be `unsigned only'? The
onyl reasonable explanation is that compiler interpretes it as
negation of positive constant. Remembering that positive constant is
`unsigned only', we deduce that compiler tries to do negation of an
unsigned type -- and having no hint assignes (willing to be negative)
result to an unsigned value. Lets try to see how the code is
interpreted:

unsigned int c=2147483648; //in times of C90 noone knew about long
long int`s.
c=-c;
cout << c;

. This yields quite obvious result of 2147483648.
That's a Sherlock-Holmes-like work of sort, so its all imho. Sorry
for a second unreliable post today.
Jan 2 '08 #12

P: n/a
On 2 ÑÎ×, 21:48, suresh <suresh.amritap...@gmail.comwrote:
int x = š-2147483648;
cout << x << endl;
//why the two parts thing you said is not applying here?
suresh
Because you've explicitely specified the type of x. In the OP
compiler has to guess the type of `2147483648' (not the same with `-'
sign) by his own and he eventually deduces it's unsigned - according
to C90 standard.
Jan 2 '08 #13

P: n/a
Hi Pavel Shved,

Wow. thanks. but can you elaborate just the part quoted below? It is
not clear to me.
suresh
>and having no hint assignes (willing to be negative)
result to an unsigned value. Lets try to see how the code is
interpreted:

unsigned int c=2147483648; //in times of C90 noone knew about long
long int`s.
c=-c;
cout << c;

. This yields quite obvious result of 2147483648.

That's a Sherlock-Holmes-like work of sort, so its all imho. Sorry
for a second unreliable post today.
Jan 2 '08 #14

P: n/a
On 2 ÑÎ×, 22:11, suresh <suresh.amritap...@gmail.comwrote:
Hi Pavel Shved,

Wow. thanks.
Nothing to thank for, really. My 2nd post is utter nonsence (it
states that float x=1/3; will not set x to 0.0).
but can you elaborate just the part quoted below? It is
not clear to me.
elaboration is up to you. I'm doing guessing only: i have no compiler
near me. The same thing as guessing is done by compiler. My code
merely shows what your code turns into if compiler's guessing rules
are same as Bo Presson described. Maybe - MAYBE - compiler's guessing
rules depend on whether you specify the type in this particular case
(your latest example). Maybe not.

But amongst these maybies there is one sure-thing. Do not let
compiler guess your types! Use Bo Persson's solution and even add
suffixes to ints there :-)
Jan 2 '08 #15

P: n/a
Jim Langston wrote:
suresh wrote:
>Hi Jim Langston,

As I understand, the range of 32 bit signed number is -2147483648 to
2147483647. So it should work correctly.

Again, the code snippet,

signed int x = -2147483648;
cout << x << endl;

works correctly though the warning "this decimal constant is unsigned
only in ISO C90" is produced.

suresh.
>>The range for a 32 bit signed number using 2's complement is
-2147483647 to 2147483648. -2147483648 does not fit in a signed 32
bit int. On a 32 bit compiler, a 32 bit number may be the largest.
Since -2147483648 does not fit in a signed 32 bit int, it seems it
is converting it to an unsigned 32 bit int.

Basically, the number you are trying to represent doesn't fit in an
int variable. I believe this is giving you an undefined value.

Undefined.
I must admit that I, too, don't see why this is undefined. The range
for a 2's complement 32-bit signed int is -2147483648 to +2147483647.

0111 1111 1111 1111 = +2147483647
1000 0000 0000 0000 = -2147483648

So why should "cout << -2147483648 << endl" fail to print correctly?

FWIW, for "cout << -2147483648 << endl" I get "2147483648" as output,
but for "cout << (-2147483647 - 1) << endl" I get "-2147483648"...

--
Mike Smith
Jan 2 '08 #16

P: n/a
Mike Smith wrote:
Jim Langston wrote:
>suresh wrote:
>>Hi Jim Langston,

As I understand, the range of 32 bit signed number is -2147483648 to
2147483647. So it should work correctly.

Again, the code snippet,

signed int x = -2147483648;
cout << x << endl;

works correctly though the warning "this decimal constant is unsigned
only in ISO C90" is produced.

suresh.
The range for a 32 bit signed number using 2's complement is
-2147483647 to 2147483648. -2147483648 does not fit in a signed 32
bit int. On a 32 bit compiler, a 32 bit number may be the largest.
Since -2147483648 does not fit in a signed 32 bit int, it seems it
is converting it to an unsigned 32 bit int.

Basically, the number you are trying to represent doesn't fit in an
int variable. I believe this is giving you an undefined value.

Undefined.

I must admit that I, too, don't see why this is undefined. The range
for a 2's complement 32-bit signed int is -2147483648 to +2147483647.
Yes, but the '-' is not part of the integer literal. It's an operator that
is applied to it. Now the C++ standard says:

"The type of an integer literal depends on its form, value, and suffix. If
it is decimal and has no suffix, it has the first of these types in which
its value can be represented: int, long int; if the value cannot be repre-
sented as a long int, the behavior is undefined."

Since 2147483648 is too big for int or long int, you get undefined behavior.
So why should "cout << -2147483648 << endl" fail to print correctly?

FWIW, for "cout << -2147483648 << endl" I get "2147483648" as output,
but for "cout << (-2147483647 - 1) << endl" I get "-2147483648"...
In this case, it's correct, because 2147483647 can be represented as a value
of type int.
Jan 2 '08 #17

P: n/a
On 2 ÑÎ×, 23:32, Mike Smith <mike_UNDERSCORE_sm...@acm.DOT.orgwrote:
So why should "cout << -2147483648 << endl" fail to print correctly?
Same reasons, same result:

unsigned int c=2147483648U;
c=-c;
cout << c << endl;
Jan 2 '08 #18

P: n/a
suresh wrote:
:: Hi Bo Persson,
::
:: Thanks for the wonderful answer. But then why did it work
:: correctly in this way?
::
:: int x = -2147483648;
:: cout << x << endl;
:: //why the two parts thing you said is not applying here?

They are. :-)

Either you have some type wider than int, like long on some compilers.
If so, you get a negative long value and convert that to an int.

Or, you don't. In that case you have the dreaded Undefined behaviour,
meaning that anything can happen. One of the things that can happen is
that it just *seems* to work (sometimes).
Bo Persson

:: suresh
::
:: On Jan 2, 9:38 pm, "Bo Persson" <b...@gmb.dkwrote:
::
::: Your value -2147483648 actually has two parts, 2147483648 and a
::: minus sign. The problem is that 2147483648 is too large to fit in
::: an int, so you really need a larger type to store it. If you
::: don't have that, you're in trouble!
:::
::: If you look in the limits.h header (or <climits>), I bet the
::: value for INT_MIN is written something like
:::
::: #define INT_MIN (-2147483647 - 1)
:::
::: to avoid this overflow.
:::
::: Bo Persson

Jan 2 '08 #19

P: n/a
Rolf Magnus wrote:
Victor Bazarov wrote:
>suresh wrote:
>>For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)

cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;

The outputs I get are:
2147483648
-2147483648,2147483647

with this compile time warning: this decimal constant is unsigned
only in ISO C90

I am surprised why the negative number is printed as positive.

Could you please explain why this behaviour?

The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'.

My compiler promoted it to unsigned long.
That's against the Standard. See [lex.icon]/2.
>If your system's 'long' has the same size as 'int' (like on Windows,
for example), the behaviour is undefined.

Try adding the suffix 'U' to the literal.

How would that help? Or did you miss that the OP actually wanted to
print a negative int value?
At least it would get rid of undefinedness.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jan 2 '08 #20

P: n/a
Victor Bazarov wrote:
Rolf Magnus wrote:
>Victor Bazarov wrote:
>>suresh wrote:
For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)

cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;

The outputs I get are:
2147483648
-2147483648,2147483647

with this compile time warning: this decimal constant is unsigned
only in ISO C90

I am surprised why the negative number is printed as positive.

Could you please explain why this behaviour?

The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'.

My compiler promoted it to unsigned long.

That's against the Standard. See [lex.icon]/2.
It says there that the behavior is undefined. Converting to unsigned long
seems perfectly valid for that.

Jan 2 '08 #21

P: n/a
Rolf Magnus wrote:
Victor Bazarov wrote:
>Rolf Magnus wrote:
>>Victor Bazarov wrote:

suresh wrote:
For this code snippet, I get the following output, which I am
unable to understand.
(2^31 = 2147483648)
>
cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;
>
The outputs I get are:
2147483648
-2147483648,2147483647
>
with this compile time warning: this decimal constant is unsigned
only in ISO C90
>
I am surprised why the negative number is printed as positive.
>
Could you please explain why this behaviour?

The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'.

My compiler promoted it to unsigned long.

That's against the Standard. See [lex.icon]/2.

It says there that the behavior is undefined. Converting to unsigned
long seems perfectly valid for that.
Yes, it is. Sorry. I guess I ought to say that it's by no means
an explanation of what happens in the OP's program. "My compiler
does this" is not a valid argument of what _shall_ happen in all
possible cases.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jan 2 '08 #22

P: n/a
On Jan 2, 5:09 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
suresh wrote:
For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)
cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;
The outputs I get are:
2147483648
-2147483648,2147483647
with this compile time warning: this decimal constant is unsigned only
in ISO C90
I am surprised why the negative number is printed as positive.
Could you please explain why this behaviour?
The literal '2147483648' does not fit in an int, therefore it
is promoted to 'long int'. If your system's 'long' has the
same size as 'int' (like on Windows, for example), the
behaviour is undefined.
My copy of the standard says that the program is ill formed if a
decimal literal does not fit in a signed integral type. Ill
formed means that it requires a diagnostic. (It's undefined
behavior in C, however, since the C standard lacks the one
sentence that says that it is ill formed.)

Of course, the current draft of the standard (and C, since C90)
support longer integral types, as do most current compilers. In
which case, the type of the literal should be long long. Which
leads to an interesting anomally: we all know that 2147483648 is
0x80000000 in hex. But if both the compiler and the library
support long long (and both will be required to real soon now),
then:

std::cout << -2147483648 << std::endl ;
// outputs "-2147483648"
std::cout << -0x80000000 << std::endl ;
// outputs 2147483648

Formally, if his machine is a 32 bit 2's complement machine,
then if the compiler supports long long (or if long has more
than 32 bits), it should output -2147483648, as he expects, and
if it doesn't, he should get a diagnostic when he compiles.

Practically: C leaves this behavior undefined, and historically,
a lot of compilers have treated a literal which didn't fit into
a long, but did fit into an unsigned long, as an unsigned. I
wouldn't be too surprised if many C++ did this as well, even if
the standard doesn't allow it. And of course, this would result
in the behavior he is seeing.
Try adding the suffix 'U' to the literal.
That certainly won't help in getting the expression be treated
as signed, which is apparently what he wants.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 2 '08 #23

P: n/a
On Jan 2, 5:19 pm, Rolf Magnus <ramag...@t-online.dewrote:
Victor Bazarov wrote:
The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'.
My compiler promoted it to unsigned long.
Presumably because it won't fit in a signed long either. That's
not legal C++ (the standard requires a diagnostic), but it does
correspond to a lot of traditional C implementations.

Try compiling is the strictest standard conformant mode.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 2 '08 #24

P: n/a
On Jan 2, 5:27 pm, suresh <suresh.amritap...@gmail.comwrote:
As I understand, the range of 32 bit signed number is -2147483648 to
2147483647. So it should work correctly.
You're correct as to the range. The problem here is that
-2147483648 is two tokens, "-" and "2147483648". The second is
a decimal integral literal. Which means (according to C++98),
that if it fits in an int, it has type int, otherwise if it fits
in a long, it has type long, otherwise, the program is ill
formed.

Historicaly, in older C compilers, the sequence of types was
int, long, unsigned long. The C standard leaves the behavior
undefined if the value doesn't fit, so that a C compiler can
legally implement the pre-standard behavior. I suspect that
your compiler is implementing the classical, pre-standard C
rules, which is permissible in C, but not in C++.

And it is a recognized problem that there is no way of entering
the smallest possible long as a decimal constant in the
language.
Again, the code snippet,
signed int x = -2147483648;
cout << x << endl;
works correctly though the warning "this decimal constant is
unsigned only in ISO C90" is produced.
This forces a conversion to signed int. Supposing for an
instance that long has more than 32 bits, or that the compiler
supports long long, then the arithmetic in the expression works,
and the results of the arithmetic on the two tokens does result
in a value that fits in a signed int. Supposing that your
compiler (illegally) treats your expression as a unsigned long
(with 32 bit longs), then the resulting value of the expression
"-2147483648" is an unsigned long with a value that doesn't fit
in a signed int. According to the standard, the results of the
conversion are implementation defined, but on most
implementations, all that happens is that the bit pattern is
stuffed into the target type. Which "happens" to give the
correct results in this case, on a 32 bit 2's complement
machine.

Just out of curiosity, what does:

std::cout << typeid( -2147483648 ).name() << std::endl ;

output on your machine?

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 2 '08 #25

P: n/a
On Jan 2, 5:32 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
suresh wrote:
People keep saying it, but...
Basically, the number you are trying to represent doesn't fit in an
int variable. I believe this is giving you an undefined value.
Undefined.
There is no undefined behavior in any of the code I've seen so
far, at least according to the C++ standard. There is a very
high probability of a compiler "error", however, or rather, a
case of the compiler intentionally being non-compliant, for
various histe^orical reasons.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 2 '08 #26

P: n/a
James Kanze wrote:
On Jan 2, 5:09 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>suresh wrote:
>>For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)
>>cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;
>>The outputs I get are:
2147483648
-2147483648,2147483647
>>with this compile time warning: this decimal constant is unsigned
only in ISO C90
>>I am surprised why the negative number is printed as positive.
>>Could you please explain why this behaviour?
>The literal '2147483648' does not fit in an int, therefore it
is promoted to 'long int'. If your system's 'long' has the
same size as 'int' (like on Windows, for example), the
behaviour is undefined.

My copy of the standard says that the program is ill formed if a
decimal literal does not fit in a signed integral type. Ill
formed means that it requires a diagnostic. (It's undefined
behavior in C, however, since the C standard lacks the one
sentence that says that it is ill formed.)
You're correct. I didn't read the next paragraph, [lex.icon]/3,
which states that the code is ill-formed if the literal cannot
be represented.

I would seem that the OP's compiler did something similar to the
compiler used by Rolf Magnus, i.e. promote the literal that it
couldn't fit into 'long' to 'unsigned long', which then gave the
expected result when unary minus was applied to it.
[..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jan 2 '08 #27

P: n/a
On Jan 2, 7:46 pm, Rolf Magnus <ramag...@t-online.dewrote:

[...]
Yes, but the '-' is not part of the integer literal. It's an operator that
is applied to it. Now the C++ standard says:
"The type of an integer literal depends on its form, value, and suffix. If
it is decimal and has no suffix, it has the first of these types in which
its value can be represented: int, long int; if the value cannot be repre-
sented as a long int, the behavior is undefined."
Where does it say that? I've got both the official C++ 98 and
the latest draft on line, and both clearly say that "A program
is ill-formed if one of its translation units contains an
integer literal that cannot be represented by any of the allowed
types". (In C99, it is undefined, because the standard doesn't
say what the behavior should be. There's no explicit statement
that the behavior is undefined there either, that I can find.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 2 '08 #28

P: n/a
James Kanze wrote:
On Jan 2, 7:46 pm, Rolf Magnus <ramag...@t-online.dewrote:

[...]
>Yes, but the '-' is not part of the integer literal. It's an operator
that is applied to it. Now the C++ standard says:
>"The type of an integer literal depends on its form, value, and suffix.
If it is decimal and has no suffix, it has the first of these types in
which its value can be represented: int, long int; if the value cannot be
repre- sented as a long int, the behavior is undefined."

Where does it say that?
I've quoted the above from C++ 98, 2.13.1/2.
I've got both the official C++ 98 and the latest draft on line,
and both clearly say that "A program is ill-formed if one of its
translation units contains an integer literal that cannot be represented
by any of the allowed types".
What exactly does it mean by "the allowed types"?

Jan 3 '08 #29

P: n/a
On 2008-01-03 01:24, Rolf Magnus wrote:
James Kanze wrote:
>On Jan 2, 7:46 pm, Rolf Magnus <ramag...@t-online.dewrote:

[...]
>>Yes, but the '-' is not part of the integer literal. It's an operator
that is applied to it. Now the C++ standard says:
>>"The type of an integer literal depends on its form, value, and suffix.
If it is decimal and has no suffix, it has the first of these types in
which its value can be represented: int, long int; if the value cannot be
repre- sented as a long int, the behavior is undefined."

Where does it say that?

I've quoted the above from C++ 98, 2.13.1/2.
>I've got both the official C++ 98 and the latest draft on line,
and both clearly say that "A program is ill-formed if one of its
translation units contains an integer literal that cannot be represented
by any of the allowed types".

What exactly does it mean by "the allowed types"?
That would be int and long int, as specified in 2.13.1/2 (long long will
probably be added in the next version of the standard).

--
Erik Wikström
Jan 3 '08 #30

P: n/a
I just get output "m" when this code segment is executed. what does
this mean?
suresh
>
Just out of curiosity, what does:

std::cout << typeid( -2147483648 ).name() << std::endl ;

output on your machine?

--
James Kanze (GABI Software) email:james.ka...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 3 '08 #31

P: n/a
Please don't top-post, and don't quote signatures.

suresh wrote:
>Just out of curiosity, what does:

std::cout << typeid( -2147483648 ).name() << std::endl ;

output on your machine?

I just get output "m" when this code segment is executed. what does
this mean?
In g++, it stands for "unsigned long".

Jan 3 '08 #32

P: n/a
Hiya James!

James Kanze wrote:
--
James Kanze (GABI Software) email:ja*********@gmail.com
[...]
Just thought I'd mention it, since Rolf pointed out Suresh quoted your
signature: Your sig is missing a blankspace after the initial two dashes
- newsreaders won't recognize this as a signature so they could
auto-remove it upon responding.

Best Regards,

Lars
Jan 3 '08 #33

P: n/a
On Jan 3, 2:05 pm, Lars Uffmann <a...@nurfuerspam.dewrote:
Hiya James!
[...]
Just thought I'd mention it, since Rolf pointed out Suresh quoted your
signature: Your sig is missing a blankspace after the initial two dashes
- newsreaders won't recognize this as a signature so they could
auto-remove it upon responding.
I'm pretty sure he doesn't miss it :)

Jan 3 '08 #34

P: n/a
On 2008-01-03 13:05, Lars Uffmann wrote:
Hiya James!

James Kanze wrote:
>--
James Kanze (GABI Software) email:ja*********@gmail.com
[...]

Just thought I'd mention it, since Rolf pointed out Suresh quoted your
signature: Your sig is missing a blankspace after the initial two dashes
- newsreaders won't recognize this as a signature so they could
auto-remove it upon responding.

Best Regards,

Lars
And you are missing both the dashes and the blankspace :-)

--
Erik Wikström
Jan 3 '08 #35

P: n/a
suresh wrote:
HI Victor,

Could you be little bit more elaborative? The max value of int in my
linux machine is 2147483648. Then why did you say that The literal
'2147483648' does not fit in an int?
Unless you have some screwball 32-bit signed magnitude signed
representation it DOES NOT.

2**31 - 1 or 2147483647 is the largest positive int value.
Jan 3 '08 #36

P: n/a
Rolf Magnus wrote:
]
My compiler promoted it to unsigned long.
Your compiler is bogus then.

2.13 Literals

A decimal literal with no suffix has the type of the first of these it
fits in: int, long int. If it doesn't fit in either, then the
behavior is undefined.

If it were octal or hexadecimal (i.e., begin with 0 or 0x), then it
would be be typed to the first of int, unsigned int, long unsigned long,
that it fits in.

"promoted" is probably the wrong term here. There's no promotion,
the type is defined by the size.
Jan 3 '08 #37

P: n/a
James Kanze wrote:
On Jan 2, 5:19 pm, Rolf Magnus <ramag...@t-online.dewrote:
>Victor Bazarov wrote:
>>The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'.
>My compiler promoted it to unsigned long.

Presumably because it won't fit in a signed long either. That's
not legal C++ (the standard requires a diagnostic), but it does
correspond to a lot of traditional C implementations.

Try compiling is the strictest standard conformant mode.
No diagnostic is required. The behavior is UNDEFINED.

I doubt seriously his compiler makes it unsigned. I've never seen
one that does it. Most do, as the OP's does, end up with a int
or long int number that doesn't actually represent the literal
expressed.
Jan 3 '08 #38

P: n/a
Erik Wikström wrote:
>Best Regards,

Lars

And you are missing both the dashes and the blankspace :-)
Might be because it's not a sig but a hand-typed personal greeting ;)

Lars
Jan 3 '08 #39

P: n/a
On Jan 3, 1:59 pm, Ron Natalie <r...@spamcop.netwrote:
James Kanze wrote:
On Jan 2, 5:19 pm, Rolf Magnus <ramag...@t-online.dewrote:
Victor Bazarov wrote:
The literal '2147483648' does not fit in an int, therefore it is
promoted to 'long int'.
My compiler promoted it to unsigned long.
Presumably because it won't fit in a signed long either. That's
not legal C++ (the standard requires a diagnostic), but it does
correspond to a lot of traditional C implementations.
Try compiling is the strictest standard conformant mode.
No diagnostic is required. The behavior is UNDEFINED.
Not according to §2.13.1/3, in C++98, C++03 and the current
draft. Both C++98 and C++03 contradict themselves, and say that
it is undefined elsewhere; this has been corrected in the
current draft.
I doubt seriously his compiler makes it unsigned.
If his compiler is g++, it makes it unsigned long.
I've never seen one that does it.
It's what C90 requires, and what g++ (and probably many other
compilers) actually do.
Most do, as the OP's does, end up with a int or long int
number that doesn't actually represent the literal expressed.
I've never seen a compiler that didn't complain if it actually
had an overflow.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jan 3 '08 #40

P: n/a
On Jan 3, 12:07 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
James Kanze wrote:
On Jan 2, 5:09 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
suresh wrote:
For this code snippet, I get the following output, which I am unable
to understand.
(2^31 = 2147483648)
>cout<< -2147483648 << endl;
cout << numeric_limits<int>::min() <<',' <<
numeric_limits<int>::max()<< endl;
>The outputs I get are:
2147483648
-2147483648,2147483647
>with this compile time warning: this decimal constant is unsigned
only in ISO C90
>I am surprised why the negative number is printed as positive.
>Could you please explain why this behaviour?
The literal '2147483648' does not fit in an int, therefore it
is promoted to 'long int'. If your system's 'long' has the
same size as 'int' (like on Windows, for example), the
behaviour is undefined.
My copy of the standard says that the program is ill formed if a
decimal literal does not fit in a signed integral type. Ill
formed means that it requires a diagnostic. (It's undefined
behavior in C, however, since the C standard lacks the one
sentence that says that it is ill formed.)
You're correct. I didn't read the next paragraph, [lex.icon]/3,
which states that the code is ill-formed if the literal cannot
be represented.
And you're correct, according to the preceding paragraph, in
C++98 and C++-03. It does happen that the standard contradicts
itself, but in this case, it does so in less than 10 lines. (I
suspect the reason is that the wording in paragraph 2 was taken
verbatum from a late draft of C99, and no one noticed that in
doing so, they accidentally introduced words to make the
behavior undefined, when they'd intentionally required a
diagnostic previously. But that's really just a guess on my
part.)

As far as I know, there was never a defect report about this
either. It's corrected in the current draft, but again, that's
perhaps just because the text taken verbatim from C99 didn't
explicitly say undefined behavior, so there is nothing which
contradicts the final statement.

Anyhow, I posted a summary of all the information I happen to
have available, and given the evolution, it's not surprising
that people (and compilers) are confused.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 3 '08 #41

P: n/a
On Jan 3, 1:05 pm, Lars Uffmann <a...@nurfuerspam.dewrote:
Hiya James!
James Kanze wrote:
--
James Kanze (GABI Software) email:james.ka...@gmail.com
[...]
Just thought I'd mention it, since Rolf pointed out Suresh
quoted your signature: Your sig is missing a blankspace after
the initial two dashes - newsreaders won't recognize this as a
signature so they could auto-remove it upon responding.
We've been through this before:-). The blank is there when I
enter the text into the post box in Google News. After that...

From what I have been able to determine: when I post from home,
the blank remains; when I post from work, it seems to be
stripped out somewhere. In both cases, I'm using the latest
version of Firefox, on a machine running Linux kernel 2.6. The
main difference I can see is that at work, the posting goes
through a firewall (over which I have no influence); it's just a
guess, but I suspect that the firewall is the problem.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 3 '08 #42

P: n/a
James Kanze wrote:
We've been through this before:-). The blank is there when I
enter the text into the post box in Google News. After that...
Ah okay - didn't realize you were aware of this - nor did I check your
header to see you were using google groups :)

Have a nice day!

Lars
Jan 4 '08 #43

P: n/a
Thanks Rolf Magnus, so this means that the g++ compiler takes
-2147483648 as unsigned long?
>
suresh wrote:
Just out of curiosity, what does:
std::cout << typeid( -2147483648 ).name() << std::endl ;
output on your machine?
I just get output "m" when this code segment is executed. what does
this mean?

In g++, it stands for "unsigned long".
Jan 4 '08 #44

P: n/a
suresh wrote:

[you just top posted again]
>suresh wrote:
>>>Just out of curiosity, what does:
std::cout << typeid( -2147483648 ).name() << std::endl ;
output on your machine?
I just get output "m" when this code segment is executed. what does
this mean?
In g++, it stands for "unsigned long".

Thanks Rolf Magnus, so this means that the g++ compiler takes
-2147483648 as unsigned long?
It interprets 2147483648 as an unsigned long (read James' post again).

On my system, the result is "long long"...

--
Ian Collins.
Jan 4 '08 #45

P: n/a
Again, please don't top-post.

suresh wrote:
> std::cout << typeid( -2147483648 ).name() << std::endl ;
>output on your machine?
I just get output "m" when this code segment is executed. what does
this mean?

In g++, it stands for "unsigned long".

Thanks Rolf Magnus, so this means that the g++ compiler takes
-2147483648 as unsigned long?
Yes. It takes 2147483648 as unsigned long, then applies the unary '-'
operator to it, and the result of that is of the same type.

Jan 4 '08 #46

P: n/a
On Jan 4, 10:38 am, Rolf Magnus <ramag...@t-online.dewrote:
suresh wrote:
std::cout << typeid( -2147483648 ).name() << std::endl ;
output on your machine?
I just get output "m" when this code segment is executed. what does
this mean?
In g++, it stands for "unsigned long".
Thanks Rolf Magnus, so this means that the g++ compiler takes
-2147483648 as unsigned long?
Yes. It takes 2147483648 as unsigned long, then applies the unary '-'
operator to it, and the result of that is of the same type.
What's annoying, of course, is that it does this even if you've
used the options for it to support long long. I'd call that a
bug. (If the compiler doesn't support long long, the behavior
is perfectly acceptable, because it does output a diagnostic, as
required by the standard.)

--
James Kanze (GABI Software) mailto:ja*********@gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34

Jan 4 '08 #47

This discussion thread is closed

Replies have been disabled for this discussion.