From: Eric Backus Subject: Bug in strtoul(), and a fix To: djgpp AT sun DOT soe DOT clarkson DOT edu (djgpp) Date: Thu, 4 Jun 92 11:29:37 PDT Mailer: Elm [revision: 66.25] I have found a bug in strtoul(). The following program demonstrates the bug: #include #include int main(int argc, char **argv) { char string[10] = "0"; char *p; unsigned long return_value; return_value = strtoul(string, &p, 0); if (return_value != 0) (void) printf("Conversion failed - returned %u\n", return_value); if (p != &string[1]) (void) printf("Pointer incorrect - offset %d from string\n", p - &string[0]); return 0; } When compiled with djgpp 1.05, this program works correctly. When compiled with djgpp 1.06, the pointer "p" is not incremented to point to string[1], but is instead left pointing to string[0]. Fortunately, the return value (zero) is correct. Strangely enough, the strtoul function found in libc.a works correctly. However, there is another strtoul function found in libgcc.a, and gcc links -lgcc before -lc into the program, so this other copy of strtoul is the one that gets used. And this other strtoul, found in libgcc.a, is the one with the bug. To fix this bug, we could probably remove strtoul from libgcc.a. This seems like the cleanest fix if it works (and I suspect that it does work), but I don't understand the purpose of libgcc.a well enough to know if this would break anything. An alternative is to fix the strtoul found in libgcc.a to work correctly. I decided to do that. The problem is that the zero character in the string is interpreted as meaning "the following number is octal", and then since there are no other characters, strtoul decides that the conversion failed. Following is a patch to strtoul.cc found in /djgpp/libsrc/gcc, that fixes the problem: *** strtoul.cc.ori Thu Jun 4 10:55:09 1992 --- strtoul.cc Thu Jun 4 10:56:48 1992 *************** *** 54,59 **** --- 54,61 ---- s++; base = 16; } + else + s--; /* Undo s++ since leading '0' is also a valid digit */ } } -- Eric Backus ericb%hplsla AT hplabs DOT hp DOT com (206) 335-2495