There are two bad things with magic numbers, one of which is intrinsic to the concept and one that just is a consequence of practicalities.
The intrinsic drawback is that it's so much harder to understand. It does not convey any information except for the raw value. A named constant is much more readable.
The practical drawback is that whenever a magical number occurs in code, it's very common that it occurs at multiple places. So if you want to change it, you need to change it at several places. It's essentially code duplication. Example:
const int no_iterations = 1000;
int sum = 0;
for(int i=0; i<no_iterations; i++) {
printf("Executing iteration %d of %d\n", i, no_iterations);
sum += foo();
}
printf("Average value: %f\n", (double)sum/no_iterations);
Without named constants, you would have to change three occurances, which can be easy to miss. Maybe you think you could just do a search and replace for the value? Nope. Consider this code:
double sphere_volume(double r) { return r*r*r*3*pi/4; }
int main()
{
double spheres[4];
// Yes, that's how to figure out the number of elemens in an array in C
for(int i=0; i<sizeof(spheres)/sizeof(spheres[0]); i++)
printf("Volume of sphere %f: %f\n", sphere_volume(sphere[i]);
}
Suppose you refactor the code by replacing all 4
with NO_ITER
and define a #define NO_ITER 4
. The code will work as before, until someone else decides that we now should change the number of iterations.
In our particular example, the code duplication is hidden. If you change the string to something else, you must ALSO remember to change the last argument. A better solution is this:
const char str[] = "/Resources";
memcpy(ResourcesDir+GameDirLen, str, sizeof(str));