Preventing Magic Numbers
This post will most likely only make sense to people who have programmed in C/C++.
It seems like trying to prevent programmers (sometimes even good programmers) from using magic numbers is a never ending task. Today, I thought of a possible idea to prevent them or at least catch them fairly quickly. Basically, you could use a preprocessor to randomly select the numerical values for #defines on each compilation. This way ever built would be internally consistent, but any attempt to hardcode a magic number would quickly fail. (Note that I’m assuming a decent unit test suite to help locate/catch the errors.) Each time the system is built, the #defines change and all the magic numbers stop working. Now we have a bunch of test failures and can easily find the “brocken” code segment. So in a header file you’d have something like this:
FLAGS(name1, name2, name3)
OR
FLAG(name1)
FLAG(name2)
FLAG(name3)
which would be respectively processed to:
#define name1 random_intOR
#define name2 random_int + 1
#define name3 random_int + 2
#define name1 random_int
#define name2 random_int2
#define name3 random_int3
You’d also need something to handle maskable flags. Currently you might have this in a header file:
#define flag1 0x01
#define flag2 0x02
#define flag3 0x04
foo(flag1 | flag2 | flag3, etc...);
You’d need to replace this with a method of auto generating the power of two masks. The new header might be:
MASKABLE_FLAGS(flag1, flag2, flag3)
The beuty of this is that all the existing tools, build structures, & code continues to work. The only thing that changes is that now the magic number usage gets quickly caught and filled as bugs. Combined with an IDE or compiler that warns on magic numbers, this might work for a fairly large software project.