K-Pad is a multi-featured notepad / organizer for Windows: print-out pages or booklets of photos, tables, and rich text.More...
This is my support blog, featuring help, tutorials, and comment. Welcome. :-)

Sunday 12 October 2008

Beware of the Macro

I try to avoid macros with C++. They're designed to reduce code, save time, and eliminate human errors, and (in theory) that's what they do. The reality, however, can be quite different.

The only macro functions I ever use are the colour-helper macros, like RGB (r,g,b).

...And min(a,b) and max(a,b)

My brain was deceived by min and max. They were lower-case, so it never registered with me properly that these were macros. But they are, and they're dangerous ones at that, because it's not intuitive as to what might happen.

Case in point: I'd been coding a text parser for times. And I used some code like
size_t const minutes = min ( 59, Text::toNumber ( getNextTextParam () ) );

What's wrong with this? Well, because if Text::toNumber ( getNextTextParam () ) returned 30, then 30 is less than 59, and then the result is not the calculated 30 but the next result of Text::toNumber ( getNextTextParam () ). In other words, the winning parameter is run again in min, max macros.

So, code like
size_t const unbound_minutes = Text::toNumber ( getNextTextParam () );
size_t const minutes = min ( 59, unbound_minutes );
would work like a charm, but it's all too easy to include extra processing in a parameter, thereby generating (at best) a slowdown, or (at worst) a serious bug.

I've now changed all my min/max's to my own inline functions Min and Max. But, fellow coders should beware!


No comments: