views:

168

answers:

2

Here is an example of one of the headaches I mean:

We have a multiplatform project that uses mostly Unicode strings for rendering text to the screen. On windows in VC++ the line:

swprintf(swWideDest, LEN, L"%s is a wide string", swSomeWideString);

compiles fine and prints the wide string into the other wide string. However, this should really be:

swprintf(swWideDest, LEN, L"%ls is a wide string", swSomeWideString);

Without replacing the '%s' with a '%ls' this will not work on other platforms. As testing in our environment on Windows is easier, quicker, and far simpler to debug. These kind of bugs can easily go unnoticed.

I know that the best solution is to write correct code in the first place, but under pressure simple mistakes are made, and in this particular case, the mistake can easily go unnoticed for a long time.

I suspect there are many variations on this sort of bug, that we are yet to enjoy.

Does anyone have a nice and neat way of finding these kind of bugs?

: D

+2  A: 

As none of the functions of *printf family are typesafe you either

  • search for probable errors via regular expressions and fix them manually
  • use another approach that is typesafe, maybe based on stringstreams or boost.format
Georg Fritzsche
The regex search does seem to be the only easy way. Was hoping to find some sort of magic compiler hack or something, but I guess brute force is the only option in this case.
Danny Parker
Sadly some limitations can't be worked around. For anything more comfortable you'd need string proccessing capabilities in the preprocessor or the compiler to typecheck the parameters based on the string contents - the preprocessor can't do it and templates can't access full string literals (but might in c++0x: http://arcticinteractive.com/2009/08/15/cpp-compile-time-string-parser-prototype/)
Georg Fritzsche
... Or not, sadly the form the idea in the link is based on was dropped from C++0x.
Georg Fritzsche
+4  A: 

You might want to have a look at FastFormat in case Boost.Format is too slow for your needs.

Compared to stringstreams and Boost.Format:

  • IOStreams: FastFormat.Format is faster than IOStreams, by between ~100-900%, in all cases
  • Boost.Format: FastFormat.Format is faster than Boost.Format, by between ~400-1650%, in all cases
Cristian Adam
I think that integrating FastFormat into our engine to replace *printf functions is the longterm solution. It should hopefully allow us to track these issues better depending on how we integrate it, but it will also perform faster which is a nice little bonus!
Danny Parker