Skip to main content
added 390 characters in body
Source Link
Christophe
  • 80.6k
  • 11
  • 132
  • 199

In short

In short

BecauseIt'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.

Avoid magic numbersSo the good practice is to avoid magic numbers. If not possible Or at least, isolategive them in your code with a name with const or a #define and, and some comments to remind how they are determined. So And if possible, isolate them in the code: in case of change, people will know where to look and how to evolve itchange them.

What it means in practice

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 assetassets. Someone willmight do a search/replace that resultswill 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 directory. THis is pretty internaldirectories behind the scene. ButBut 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

Terminological remark

The term "magic number" has multiple meanings. I handled it here in the sense of "a unique unexplained value", and not in the more common meaning of a special couple of bytes at the beginning of a file to give a hint about its content :

  • 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.

In short

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.

Avoid magic numbers. If not possible, isolate them in your code with a const or a #define and some comments to remind how they are determined. So in case of change, people know where to look and how to evolve it.

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 asset. Someone will do a search/replace that results 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 directory. THis is pretty internal. 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 value", and not in the more common meaning of a special couple of bytes at the beginning of a file to give a hint about its content

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.
added 383 characters in body
Source Link
Christophe
  • 80.6k
  • 11
  • 132
  • 199

In short

Because magic number"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.

Avoid magic numbers. If not possible, isolate them in your code with a const or a #define and some comments to remind how they are determined. So in case of change, people know where to look and how to evolve it.

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 asset. Someone will do a search/replace that results 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 directory. THis is pretty internal. 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

Avoid magic numbers. If not possible, isolate them in your code with a const or aThe term #define and some comments to remind how they are determinedmagic number has multiple meanings. So I handled it here in casethe sense of change"a unique unexplained value", people know where to look and hownot in the more common meaning of a special couple of bytes at the beginning of a file to evolve it.give a hint about its content

Because magic number 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.

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 asset. Someone will do a search/replace that results 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 directory. THis is pretty internal. 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...

Avoid magic numbers. If not possible, isolate them in your code with a const or a #define and some comments to remind how they are determined. So in case of change, people know where to look and how to evolve it.

In short

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.

Avoid magic numbers. If not possible, isolate them in your code with a const or a #define and some comments to remind how they are determined. So in case of change, people know where to look and how to evolve it.

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 asset. Someone will do a search/replace that results 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 directory. THis is pretty internal. 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 value", and not in the more common meaning of a special couple of bytes at the beginning of a file to give a hint about its content

Source Link
Christophe
  • 80.6k
  • 11
  • 132
  • 199

Because magic number 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.

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 asset. Someone will do a search/replace that results 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 directory. THis is pretty internal. 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...

Avoid magic numbers. If not possible, isolate them in your code with a const or a #define and some comments to remind how they are determined. So in case of change, people know where to look and how to evolve it.