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

Strange behaviour, bug in Borland compiler?

P: n/a
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;

You will get:

x == 1 with Borland C++ Builder
x == 0 with Microsoft Visual Studio

"int" is 32 bit in both compilers.
So the result should be the same.
Is this a bug in the Borland compiler?

Greetings,
Markus Sandheide
Jul 22 '05 #1
Share this Question
Share on Google+
20 Replies


P: n/a
Markus Sandheide wrote:
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;

You will get:

x == 1 with Borland C++ Builder
x == 0 with Microsoft Visual Studio

"int" is 32 bit in both compilers.
So the result should be the same.
Is this a bug in the Borland compiler?


It looks like a missing in your C++ knowledge. Read an up to date ISO
C++ book.
You may check http://www.accu.org at the book reviews section.
Also take a look at a page of mine:

http://www23.brinkster.com/noicys/learningcpp.htm


--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #2

P: n/a
Markus Sandheide wrote:

Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;

You will get:

x == 1 with Borland C++ Builder
x == 0 with Microsoft Visual Studio

"int" is 32 bit in both compilers.
So the result should be the same.
Is this a bug in the Borland compiler?


Looks like a bug in Borland C++ Builder

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #3

P: n/a
Ioannis Vranos wrote:
It looks like a missing in your C++ knowledge. Read an up to date ISO
C++ book.
You may check http://www.accu.org at the book reviews section.
Also take a look at a page of mine:

http://www23.brinkster.com/noicys/learningcpp.htm

In other words check the following code in both compilers:
#include <iostream>
#include <limits>
int main()
{
using namespace std;

int x=1;

cout<< (x > numeric_limits<int>::max()) <<"\n";
}


--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #4

P: n/a
Ioannis Vranos wrote:

Markus Sandheide wrote:
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;

You will get:

x == 1 with Borland C++ Builder
x == 0 with Microsoft Visual Studio

"int" is 32 bit in both compilers.
So the result should be the same.
Is this a bug in the Borland compiler?


It looks like a missing in your C++ knowledge.


Hmm. Then I am guilty too.
What am I missing? Could you enlighten me?

x is of type int with a value in its range
2345678901 is of type int with a value in its range (32 bit)
So there should be no problem in comparing those numbers.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #5

P: n/a
On Tue, 04 Jan 2005 14:52:39 +0100, Karl Heinz Buchegger
<kb******@gascad.at> wrote:
Ioannis Vranos wrote:

Markus Sandheide wrote:
> Hello!
>
> Execute these lines:
>
> int x = 1;
> x = x > 2345678901;
>
> You will get:
>
> x == 1 with Borland C++ Builder
> x == 0 with Microsoft Visual Studio
>
> "int" is 32 bit in both compilers.
> So the result should be the same.
> Is this a bug in the Borland compiler?


It looks like a missing in your C++ knowledge.


Hmm. Then I am guilty too.
What am I missing? Could you enlighten me?

x is of type int with a value in its range
2345678901 is of type int with a value in its range (32 bit)
So there should be no problem in comparing those numbers.


but the expression x > 2345678901 is of type bool, and its boolean result
is then converted to an int...
i do not think that there are any prescriptions in the standard saying
that false must be converted to 0
(however, it is bad style anyway to mess with types in such a way)
Jul 22 '05 #6

P: n/a
Markus Sandheide wrote:
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;


2345678901 is not representable in a signed 32-bit int. Try with x=x>5, it
should give the correct result. Do you not get any warning when compiling this?

Christian
Jul 22 '05 #7

P: n/a
Karl Heinz Buchegger wrote:
Hmm. Then I am guilty too.
What am I missing? Could you enlighten me?

x is of type int with a value in its range
2345678901 is of type int with a value in its range (32 bit)


int is *signed* int and is of the range -2147483648..2147483647 for 32bit.
2345678901 is therefore out of range, except for *unsigned* int.

Christian
Jul 22 '05 #8

P: n/a
Ulrich Achleitner wrote:

On Tue, 04 Jan 2005 14:52:39 +0100, Karl Heinz Buchegger
<kb******@gascad.at> wrote:
Ioannis Vranos wrote:

Markus Sandheide wrote:

> Hello!
>
> Execute these lines:
>
> int x = 1;
> x = x > 2345678901;
>
> You will get:
>
> x == 1 with Borland C++ Builder
> x == 0 with Microsoft Visual Studio
>
> "int" is 32 bit in both compilers.
> So the result should be the same.
> Is this a bug in the Borland compiler?

It looks like a missing in your C++ knowledge.


Hmm. Then I am guilty too.
What am I missing? Could you enlighten me?

x is of type int with a value in its range
2345678901 is of type int with a value in its range (32 bit)
So there should be no problem in comparing those numbers.


but the expression x > 2345678901 is of type bool, and its boolean result
is then converted to an int...
i do not think that there are any prescriptions in the standard saying
that false must be converted to 0


There are

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #9

P: n/a
Christian Gollwitzer wrote:

Karl Heinz Buchegger wrote:
Hmm. Then I am guilty too.
What am I missing? Could you enlighten me?

x is of type int with a value in its range
2345678901 is of type int with a value in its range (32 bit)


int is *signed* int and is of the range -2147483648..2147483647 for 32bit.
2345678901 is therefore out of range, except for *unsigned* int.


Ah. Shit.
I just used my desktop calculator: 2^32 - 1
For signed int it needs to be: 2^31 - 1

Thanks

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #10

P: n/a
Karl Heinz Buchegger wrote:
but the expression x > 2345678901 is of type bool, and its boolean result
is then converted to an int...
i do not think that there are any prescriptions in the standard saying
that false must be converted to 0


There are


To elaborate:

4.5 Integral promotions

4 An rvalue of type bool can be converted to an rvalue of type int, with false
becoming zero and true becoming one

It turned out, that my math was simply wrong.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #11

P: n/a
On Tue, 04 Jan 2005 14:50:52 +0100, Christian Gollwitzer
<au******@btcips73x1.cip.uni-bayreuth.de> wrote:
Markus Sandheide wrote:
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;


2345678901 is not representable in a signed 32-bit int. Try with x=x>5, it
should give the correct result. Do you not get any warning when compiling this?


Borland 5.5.1 doesn't warn about the above. However, change this to:

#include <iostream>
int main()
{
using namespace std;
int x=1;
unsigned int y = 2345678901;
x = x > y;
cout << x << endl;
}

and you get this:
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
Warning W8012 10: Comparing signed and unsigned values in function
main()

Output is 0 when using a variable.

--
Bob Hairgrove
No**********@Home.com
Jul 22 '05 #12

P: n/a

"Markus Sandheide" <ms********@yahoo.de> wrote in message
news:f1**************************@posting.google.c om...
Re: Strange behaviour, bug in Borland compiler?
The behavior isn't 'strange', it's undefined.
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;
The value 2345678901 is outside the range of
a 32-bit signed int. You're not comparing 'x'
against 2345678901, but some unknown, undefined
value. You could get any result at all.

You will get:

x == 1 with Borland C++ Builder
x == 0 with Microsoft Visual Studio
Or possibly something else with another compiler, or
a different version of those compilers, or with the
same version of them, running the program again.

"int" is 32 bit in both compilers.
So the result should be the same.
The result is undefined.
Is this a bug in the Borland compiler?


No, the bug is in your code. The maximum possible
value for 32-bit signed int is 2147483647.

Try changing the type to unsigned int.

-Mike
Jul 22 '05 #13

P: n/a
Christian Gollwitzer wrote:
Markus Sandheide wrote:
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;
2345678901 is not representable in a signed 32-bit int.


But it is representable in an unsigned 32-bit int.
Try with x=x>5, it should give the correct result.
Are you trying to say that 1 is the correct result
for the original case?
Do you not get any warning when compiling this?

No diagnostic is required. (although it would be nice
if there were).

Jul 22 '05 #14

P: n/a
> No, the bug is in your code. The maximum possible
value for 32-bit signed int is 2147483647.


Then there is a bug in the Microsoft Foundation Classes C++ library:

Have a look at CByteArray::SetSize, you can find it here:
http://www.dpi.ufv.br/downloads/C++%...RC/ARRAY_B.CPP

There is this line:
ASSERT(nNewSize <= SIZE_T_MAX/sizeof(BYTE));

nNewSize is an int and SIZE_T_MAX is UINT_MAX.

If you compile this code in debug mode with Borland the ASSERT fails
because of the differtent behaviour of Borland that I described.
Markus Sandheide

Jul 22 '05 #15

P: n/a
No, the bug is in your code. The maximum possible
value for 32-bit signed int is 2147483647.


Then there is a bug in the Microsoft Foundation Classes C++ library:

Have a look at CByteArray::SetSize, you can find it here:
http://www.dpi.ufv.br/downloads/C++%...RC/ARRAY_B.CPP

There is this line:
ASSERT(nNewSize <= SIZE_T_MAX/sizeof(BYTE));

nNewSize is an int and SIZE_T_MAX is UINT_MAX.

If you compile this code with Borland the ASSERT always fails because
of the different behaviour of Borland that I described.
Markus Sandheide

Jul 22 '05 #16

P: n/a
Old Wolf wrote:
Christian Gollwitzer wrote:
Markus Sandheide wrote:
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;
2345678901 is not representable in a signed 32-bit int.


But it is representable in an unsigned 32-bit int.


OK, so if you understand it as an unsigned integer constant, you would have a
comparison between signed int x and unsigned int constant. I'd expect that this
gives undefined behaviour, though I don't have the standard to check against.
Try with x=x>5, it should give the correct result.


Are you trying to say that 1 is the correct result
for the original case?


?? I say, the line x= x>5 should produce x==0 in any case, because 1>5 is false.
It should not depend on the compiler. If it does, it is a compiler bug.
Do you not get any warning when compiling this?


No diagnostic is required. (although it would be nice
if there were).


After completing the example:

#include <iostream>

int main() {
int x = 1;
x = x > 2345678901;
std::cout<<x<<std::endl;
return 0;
}

g++ -Wall gives me:

test.cpp: In function `int main()':
test.cpp:5: Warnung: this decimal constant is unsigned only in ISO C90
test.cpp:5: Warnung: comparison between signed and unsigned integer expressions

and marking the constant as unsigned "2345678901u"

test.cpp: In function `int main()':
test.cpp:5: Warnung: comparison between signed and unsigned integer expressions

so in any case, I get the "comparison between signed and unsigned" warning as
expected.

Christian

Jul 22 '05 #17

P: n/a
On 4 Jan 2005 05:33:24 -0800, ms********@yahoo.de (Markus Sandheide)
wrote in comp.lang.c++:
Hello!

Execute these lines:

int x = 1;
x = x > 2345678901;

You will get:

x == 1 with Borland C++ Builder
x == 0 with Microsoft Visual Studio

"int" is 32 bit in both compilers.
So the result should be the same.
Is this a bug in the Borland compiler?

Greetings,
Markus Sandheide


Mike Whaler has it mostly right, and quite a few other people have it
wrong.

A decimal literal without a suffix indicating that it is unsigned
NEVER becomes an unsigned type in either C or C++.

In C++, the type of a decimal literal is int if its value is within
the range of signed int. It its value is outside the range of signed
int, it has type signed long if it is within the range of signed long.

2345678901 is greater than INT_MAX for a 32-bit 2's complement signed
int. But since both the compilers you use have 32-bit 2's complement
signed long, it also outside the range of values for signed long. So
the result is undefined behavior.

Note that if compiled and executed this program on a platform where
int has 32 bits and long has 64 bits, such as 64 bit Windows and
perhaps some others, then the literal would easily fit into a signed
long. In the comparison 'x' would get promoted to signed long and the
result would be false.

Since you are not using an implementation where signed int or signed
long has more than 32-bits, neither compiler is right or wrong as far
as the language is concerned. There is no right or wrong once you
produce undefined behavior.

--
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
Jul 22 '05 #18

P: n/a
Karl Heinz Buchegger wrote:

Hmm. Then I am guilty too.
What am I missing? Could you enlighten me?

x is of type int with a value in its range
2345678901 is of type int with a value in its range (32 bit)
So there should be no problem in comparing those numbers.


That number is too big for a signed 32 bit int, so it's converted
to unsigned. The test should still work (1 gets promoted to unsigned
1).
Jul 22 '05 #19

P: n/a
Christian Gollwitzer wrote:
Old Wolf wrote:
Christian Gollwitzer wrote:
Markus Sandheide wrote:
int x = 1;
x = x > 2345678901;

2345678901 is not representable in a signed 32-bit int.
But it is representable in an unsigned 32-bit int.


OK, so if you understand it as an unsigned integer constant,
you would have a comparison between signed int x and unsigned
int constant. I'd expect that this gives undefined behaviour


In fact the signed int is converted to unsigned and then they
are compared. The conversion works by modular arithmetic
(ie. you add or subtract TYPE_MAX+1 from the signed value until
it is in the range of the unsigned value). So the comparison
becomes 1U > 2345678901U .
Try with x=x>5, it should give the correct result.


Are you trying to say that 1 is the correct result
for the original case?


??


Sorry , bad wording by me -- 0 is the correct result
It should not depend on the compiler.
If it does, it is a compiler bug.
There are some things in C where the result depends on the compiler
(although this case should not be one of them)
Do you not get any warning when compiling this?

No diagnostic is required.


g++ -Wall gives me:

test.cpp: In function `int main()':
test.cpp:5: Warnung: this decimal constant is unsigned only in ISO

C90

Looking at the C99 draft, it appears as if 2345678901 is a
signed long long. (The result of 1LL > 2345678901LL is still 0).
test.cpp:5: Warnung: comparison between signed and unsigned integer
expressions
so in any case, I get the "comparison between signed and unsigned"
warning as expected.


Right. The Borland compiler doesn't give you the warning --
it's entitled to not do that. (Although it should give the
correct answer!) Have you tried with Borland 5.6.4 ?

Jul 22 '05 #20

P: n/a
Ron Natalie wrote:
Karl Heinz Buchegger wrote:

Hmm. Then I am guilty too.
What am I missing? Could you enlighten me?

x is of type int with a value in its range
2345678901 is of type int with a value in its range (32 bit)
So there should be no problem in comparing those numbers.


That number is too big for a signed 32 bit int, so it's converted
to unsigned. The test should still work (1 gets promoted to unsigned
1).


As Jack Klein has already pointed out, such is not the case.

Would've caught me too: I forget that decimal literals don't work
the same as octal or hexadecimal.
Jul 22 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.