BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Potential BCC32 integer promotion bug

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Command Line Tools)
View previous topic :: View next topic  
Author Message
Marcus Holland-Moritz
Guest





PostPosted: Wed Apr 14, 2004 8:44 am    Post subject: Potential BCC32 integer promotion bug Reply with quote



I think I've found a bug in bcc32 5.5.1. Here's some code that triggers
the bug:

-----------------------------------------------------------------------
#include <stdio.h>

#define check(cond)
printf("%s => %sn", #cond, (cond) ? "correct" : "incorrect");

#define MAXUINT ((unsigned int)~0)

int main(void)
{
signed int i = 42;
unsigned int u = 42;

check(i < MAXUINT);
check(u < MAXUINT);

return 0;
}
-----------------------------------------------------------------------

The example shows that integer promotion isn't working according to the
ANSI standard. Here's the excerpt from the standard:

[...]
"Otherwise, the integer promotions are performed on both operands.
Then the following rules are applied to the promoted operands:

1) If both operands have the same type, then no further conversion
is needed.

2) Otherwise, if both operands have signed integer types or both
have unsigned integer types, the operand with the type of lesser
integer conversion rank is converted to the type of the operand
with greater rank.

3) Otherwise, if the operand that has unsigned integer type has rank
greater or equal to the rank of the type of the other operand,
then the operand with signed integer type is converted to the
type of the operand with unsigned integer type.

4) Otherwise, if the type of the operand with signed integer type
can represent all of the values of the type of the operand with
unsigned integer type, then the operand with unsigned integer
type is converted to the type of the operand with signed integer
type.

5) Otherwise, both operands are converted to the unsigned integer
type corresponding to the type of the operand with signed
integer type."
[...]

Rule 3) ensures that in the above code both checks succeed.
Both MAXUINT and i/u are types of the same rank. Thus, i shall
be promoted to an unsigned integer before comparison with MAXUINT.
The second check with u is trivial. However, the code, when run,
should print "correct" twice.

It doesn't with bcc32:

D:disttest>bcc32 bug.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
bug.c:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

D:disttest>.bug
i < MAXUINT => incorrect
u < MAXUINT => correct

It does, however, with both MingGW/gcc and Microsoft CL:

D:disttest>gcc --version
gcc (GCC) 3.2.3 (mingw special 20030504-1)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

D:disttest>gcc -o bug.exe bug.c

D:disttest>.bug
i < MAXUINT => correct
u < MAXUINT => correct

D:disttest>cl /o:bug.exe bug.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

bug.c
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:bug.exe
/out::bug.exe
bug.obj

D:disttest>.bug
i < MAXUINT => correct
u < MAXUINT => correct

It also does with Cygwin/gcc:

mhx@skywalker ~
$ cc --version
cc (GCC) 3.3.1 (cygming special)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

mhx@skywalker ~
$ cc -o bug.exe bug.c

mhx@skywalker ~
$ ./bug
i < MAXUINT => correct
u < MAXUINT => correct

I've come across this problem while compiling Perl on Windows using
the Borland compiler. There's code similar to the above example in
the Perl source.

Marcus
Back to top
Cesar Rabak
Guest





PostPosted: Thu Apr 15, 2004 3:16 pm    Post subject: Re: Potential BCC32 integer promotion bug Reply with quote



Marcus Holland-Moritz escreveu:
Quote:
I think I've found a bug in bcc32 5.5.1. Here's some code that triggers
the bug:

-----------------------------------------------------------------------
#include <stdio.h

#define check(cond)
printf("%s => %sn", #cond, (cond) ? "correct" : "incorrect");

#define MAXUINT ((unsigned int)~0)

int main(void)
{
signed int i = 42;
unsigned int u = 42;

check(i < MAXUINT);
check(u < MAXUINT);

return 0;
}
-----------------------------------------------------------------------

The example shows that integer promotion isn't working according to the
ANSI standard. Here's the excerpt from the standard:

[...]
"Otherwise, the integer promotions are performed on both operands.
Then the following rules are applied to the promoted operands:

1) If both operands have the same type, then no further conversion
is needed.

2) Otherwise, if both operands have signed integer types or both
have unsigned integer types, the operand with the type of lesser
integer conversion rank is converted to the type of the operand
with greater rank.

3) Otherwise, if the operand that has unsigned integer type has rank
greater or equal to the rank of the type of the other operand,
then the operand with signed integer type is converted to the
type of the operand with unsigned integer type.

4) Otherwise, if the type of the operand with signed integer type
can represent all of the values of the type of the operand with
unsigned integer type, then the operand with unsigned integer
type is converted to the type of the operand with signed integer
type.

5) Otherwise, both operands are converted to the unsigned integer
type corresponding to the type of the operand with signed
integer type."
[...]

Rule 3) ensures that in the above code both checks succeed.
Both MAXUINT and i/u are types of the same rank. Thus, i shall
be promoted to an unsigned integer before comparison with MAXUINT.
The second check with u is trivial. However, the code, when run,
should print "correct" twice.

It doesn't with bcc32:

D:disttest>bcc32 bug.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
bug.c:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

D:disttest>.bug
i < MAXUINT => incorrect
u < MAXUINT => correct

[snipped]


Quote:
I've come across this problem while compiling Perl on Windows using
the Borland compiler. There's code similar to the above example in
the Perl source.

Marcus,


FWIW, the symptom above also appears w/the bcc32 that comes w/CBuildeX
demo version:


D:test>bcc32 ..integer_bug.c
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
...integer_bug.c:
Turbo Incremental Link 5.65 Copyright (c) 1997-2002 Borland

D:test>dir
O volume na unidade D é DADOS
O número de série do volume é 0A53-10FE

Pasta de D:test

25/10/2003 19:36 <DIR> .
25/10/2003 19:36 <DIR> ..
15/04/2004 12:09 55.808 integer_bug.exe
15/04/2004 12:09 610 integer_bug.obj
15/04/2004 12:09 393.216 integer_bug.tds
3 arquivo(s) 449.634 bytes
2 pasta(s) 16.695.410.688 bytes disponíveis

D:test>integer_bug.exe
i < MAXUINT => incorrect
u < MAXUINT => correct


HTH

--
Cesar Rabak


Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Command Line Tools) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.