In short
It's a bad practice because "magic numbers" make localization and maintenance more difficult, since someone else (or a future version of you) will not know (anymore) why this magic number was as it was.
So the good practice is to avoid magic numbers. Or at least, give them a name with const
or #define
, and some comments to remind how they are determined. And if possible, isolate them in the code: in case of change, people will know where to look and how to change them.
What it means in practice
Your simple example requires some imagination to demonstrate the issue: Suppose the new art director of your game company decides that all the resources should from now on considered as assets. Someone might do a search/replace that will result in:
memcpy(ResourcesDir+GameDirLen, "/GameAssets", 11); // OUCH!!!
Or maybe someone decides that resources are fun and adds some smiley (UTF8 encoded of course):
memcpy(ResourcesDir+GameDirLen, "/Ress🙂urces", 11); // OUCH!!! x3
// (because of 4 bytes encoding instead of 1)
Everything will compile. But in the first case you've lost your trailing '\0'
, which might cause buffer overflows. And in the second case, the buffer overflow is already there: your new release will ruin all the past success of your game because of security considerations and bad quality.
Your example is about a directories behind the scene. But now imagine that it's about dialogues and messages that have to be translated in several languages, each using a translation of different length...
Terminological remark
The term "magic number" has multiple meanings :
- I handled it here in the sense of "a unique unexplained constant value", and not in the other common meaning of a special integer at the beginning of a file to give a hint about the file's content.
- As there are some fierce battle about what a magic number is, it may be worth mentioning that some well known secure coding standards and organisations use the term likewise.