The Daily WTF for 2008-11-28 pillories the following code:
static char *nice_num(long n) { int neg = 0, d = 3; char *buffer = prtbuf; int bufsize = 20; if (n < 0) { neg = 1; n = -n; } buffer += bufsize; *--buffer = '\0'; do { *--buffer = '0' + (n % 10); n /= 10; if (--d == 0) { d = 3; *--buffer = ','; } } while (n); if (*buffer == ',') ++buffer; if (neg) *--buffer = '-'; return buffer; }
How would you write it?
If you’re a seasoned C programmer, you’ll realize this code isn’t actually that bad. It’s relatively straightforward (for C), and it’s blazingly fast. It has three problems:
Problem #1 is easily solved with a special case. To address #2, I’d separate the code into two functions, one for 32-bit integers and one for 64-bit integers. #3 is a little harder – we have to change the interface to make completely thread-safe.
Here is my solution, based on this code but modified to address these problems:
Explanation: it creates a local buffer on the stack and then fills that in in the same method as the initial code. Then, it copies it into a parameter passed into the function, making sure not to overflow the buffer. It also has a special case for INT32_MIN. The return value is 0 if the original buffer was large enough, or 1 if the buffer was too small and the resulting string was truncated.