A tale of C abstraction
(Totally not based on actual events. Nope. Not at all.)
Suppose you’re writing C code and you have these attributes, not necessarily exclusive, that are associated with an entity. There are less than 32 of them, so using an integer as a bit array is a very C thing to do. So do that. Seems like a reasonable start.
enum {
active,
inert,
snuggly,
snarf_like,
changable,
used,
noted,
special,
more_special,
// etc.
};
After a while you see you’re doing this sort of thing a lot.
if ((mask & (1 << active))
|| (mask & (1 << inert))
|| (mask & (1 << changable))
|| /* etc */) {
// Stuff happens here
}
Not only that, but you have to check these bits in different ways. One way is to check for a set of exclusive values (like the above snippet), other ways are to look for specific combinations, and those combinations can involve a lot of different attributes.
You get annoyed writing them all out. Ugh! It’s so obnoxious.
Perhaps it’s time to abstract that away to be clearer less typing.
After all, you’re getting tired of repeating yourself.
And it’s all about you and programmer productivity, right?
So what is available? Well, there’s that old stalwart of abstraction, the function. But man, those functions, they’re soooo slow. Remember back in school when you overheard that grumpy systems programmer complaining that C coders (who should really be writing assembly) were wasting so much processor time pushing values on the stack and “those amateurs” (his words!) should be using macros to make more efficient use of their precious machine resources? That guy was full of wisdom. And he never had to use a debugger! Not just wise, but a true hacker. You don’t want to disappoint him.
Better break out the macros.
It turns out this pattern is showing up in a lot of files, and it’s even more regular than you thought. The same set of checks are run together all the time