This is the first in a series of snippets that present code that I personally consider an affront to humanity. All code must be from real, live projects. If the code is proprietary in origin, or otherwise confidential, symbol names might be changed to protect the guilty, but it’s ALL REAL. YMMV.
Today’s crime against humanity:
Returning from a within a macro
Witness this innocent chunk of code, from fs/intermezzo/journal.c in a kernel tree near you:
#define BUFF_ALLOC(newbuf, oldbuf) \
PRESTO_ALLOC(newbuf, PAGE_SIZE); \
if ( !newbuf ) { \
if (oldbuf) \
BUFF_FREE(oldbuf); \
return -ENOMEM; \
}
Do I really need to explain why returning from a macro is a bad, bad, bad, god awful idea? consider:
void foo(void)
{
void* buf1, buf2, buf3;
BUFF_ALLOC(buf1, NULL);
BUFF_ALLOC(buf2, buf1);
BUFF_ALLOC(buf3, buf2); <----- BOOOM. Bye bye buf1 memory if
allocation fails.
}
Resource allocation and deallocation should always be handled with care. Sequence points where resource book keeping is required must be explicit.
