Archive for December, 2007

My Favorite C++ Macro

December 18th, 2007 No comments

It is widely understood that C/C++ preprocessor macros are dangerous and should be avoided, especially when they can easily be replaced by a constant or template. However, there’s one macro I came up with that I really like:

#define MAKE_STRING(v) (static_cast<std::ostringstream&>(std::ostringstream().flush() << v)).str()

And here’s an example usage:

float x = 3.14f;
std::string x = MAKE_STRING("The value of x is " << x);

This macro dispenses with all the annoying boilerplate of setting up an ostringstream, writing to it, and storing the result in a string. It takes advantage of the fact that the stream insertion operator (<<) returns the stream that was passed to it, so we can chain together a bunch of insertions, cast the result back to an ostringstream and get the resulting string. Undoubtedly, there are more “elegant” ways to do this with templates. Here’s why I like this macro:

  • It’s simple
  • It’s one line so I can throw it into a project without pulling in all of boost
  • The usage is very intuitive

It also makes a nice base for, say a log4cxx wrapper:

#define LOG_INFO(v) getLogger()->info(MAKE_STRING(v))

Now logging mixed types is a snap, and you can turn off all logging with a simple preprocessor conditional.

Caveats? Of course there are…

  • Still suffers from multiple evaluation problems typical of all macros with value arguments
  • Probably not all that fast

Neither of these has bitten me yet in several years of use. Be careful though, it’s viral. Once I showed it to my coworkers it started springing up everywhere for better and worse :)

Categories: c++ Tags:

Concurrency – A paper and a war story

December 7th, 2007 No comments

Today I came across two nicely related blog posts. In the first, Alexander Schatten gives excerpts from a paper (PDF) detailing what a lot of people have a sneaking suspicion about: getting concurrency right is really really tricky, even if you know what you’re doing. I’m glad the paper discusses listeners in a multi-threaded environment because every deadlock I’ve had lately seems to involve listeners being invoked while a lock is held.

In the second blog post, Marc relates a great war story where he channels Gene Kranz from Apollo 13: “Let’s work the problem people. Let’s not make things worse by guessing”. It’s really a textbook example of systematically understanding and working through a problem. In relation to concurrency, the problem he tracks down and fixes is a perfect example of how tricky multi-threading can be.

Categories: concurrency Tags: