Every year Google conducts a programming competition called Google CodeJam. Last year I registered for it. The competition was hosted by a site called TopCoder. Since then, TopCoder keeps sending me a mail once in a while announcing a new competition. So recently I visited their site to get myself unsubscribed from their mailing list. That’s when I stumbled upon a really neat article titled “Five Things You Didn't Know About C++”. It’s actually a list on ten, not five, interesting facts about C/C++. ‘Macro recursion’ as they called it was one of them, although it’s actually more to do with the C preprocessor than the language itself.
Any C programmer worth his salt knows that it is not possible to recursively call a macro. But have you ever wondered what would happen if did? What would happen if you use the name of a macro in the definition of that macro? No, it will not give you a preprocessor error. It will just be left as it is. The preprocessor will do only one round of expansion. You might then go on to get a compiler error because of an undefined symbol in the code. But what if it is not an undefined symbol? What if the macro has the same name as a valid function? Yes, it will compile successfully and the function will be called when the code is run.
This opens up an interesting possibility. You could use this technique to create a ‘transparent wrapper’. Suppose you are hitting a panic in your code. You suspect that you're inadvertently passing a zero as size to a malloc somewhere and causing a buffer overflow when you attempt to write to it. An easy way to catch this bug would be to #define malloc(x) (assert(x > 0); malloc(x);). The assert() will report the file and line number of your bug. So much for a bug’s life.
No comments:
Post a Comment