Subtle bugs stink
Consider the following piece of code, to process hex color strings:
sscanf(text, “#%2x%2x%2x%2x”, &rgbcolor.r, &rgbcolor.g, &rgbcolor.b, &rgbcolor.a);
Looks pretty standard, eh? Well, that piece of code cost a day’s work. I was getting segmentation faults in std::list’s iterator post-increment. The iterator had no clear reason to be invalid, although the debugger did show bad values (0×0 or 0xbf000000 for the _M_node internal pointer it was trying to dereference). I copied my project, and hacked it down to a smaller main code path. Strangely enough, the presence the constructor for an otherwise unused class was the shibboleth that determined whether my code crashed or not. Suspecting a compiler bug (how pride resists being wounded!), I tried all manner of settings (optimization, static vs. dynamic linking) before I finally went back to said constructor. Lo and behold, when the constructor called a code path that involved the sscanf above, std::list exploded. When not, it was fine. What on earth?
Well kids, this is why C-style formatters are considered harmful. Sure I had four %x’s and four variables, but “%x”es expect ‘int’ and my variables happened to be ‘char’s underneath a typedef. So the problem was not in std::list, not in the derived class, not in my main code and not even directly in the constructor that clued me in.
Using C++ stringstreams can be a pain, but so is debugging things like this. I wonder if that’s why C++ often gets a bum rap.