 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Marcus Holland-Moritz Guest
|
Posted: Wed Apr 14, 2004 8:44 am Post subject: Potential BCC32 integer promotion bug |
|
|
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
|
Posted: Thu Apr 15, 2004 3:16 pm Post subject: Re: Potential BCC32 integer promotion bug |
|
|
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 |
|
 |
|
|
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
|
|