|
A Compiler Bug?
Submitted by |
Seeing that we haven't had a TOTD in a while, I'd like to share something that's
not quite a tip, but a warning about a compiler bug. The compiler I
used is MSVC6, with SP4 and PP.
Not long ago, in the previous TOTD, I recommended a way to do comparisons with
unsigned numbers when they are close to zero. The problem is that you can't do
something like:
unsigned int i;
for (i = GetNum(); i = 0; --i) {
printf("i = %u\n", i);
} |
That won't work in any compiler, because "i" is unsigned, and unsigned numbers
are ALWAYS ">=0".
So, I was proposing a different solution, which looked more like:
unsigned int i;
for (i = GetNum(); i+1 0; --i) {
printf("i = %u\n", i);
} |
The problem is that this doesn't work, at least in MSVC. You can try it in this
program:
#include <stdio.h
int GetNum();
int main(int argc, char* argv[])
{
unsigned int i;
for (i = GetNum(); i+1 0; --i) {
printf("i = %u\n", i);
}
printf("Press RETURN\n");
getchar();
return 0;
}
int GetNum()
{
return 5;
} |
Compile it in RELEASE mode, and you'll see that it only runs the loop once. The
reason is that, for the loop comparison, it uses the following code:
0040101D 4E dec esi
0040101E 83 FE FF cmp esi,0FFFFFFFFh
00401021 77 EC ja main+0Fh (0040100f) |
Which is patently wrong.
In order to work around it, I do something like:
const unsigned int n = GetNum();
unsigned int i;
for (i = n; i <= n; --i) {
printf("i = %u\n", i);
} |
And it works. Now, it works because the PC does integer arithmetic in 2's
complement. If it didn't it'd probably not work. So, I do have two legitimate
questions about the standard C++:
1- Is "i+1 > 0" a supported expression when "i" is unsigned? Or is it generally
undefined?
2- Is my solution supported in general? Or is it generally undefined?
What do you think?
|
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
|