Clever Geek Handbook
📜 ⬆️ ⬇️

Magic number (programming)

The concept of " magic number " in programming has three meanings:

  • Data signature
  • Highlighted unique values ​​that should not coincide with other values ​​(for example, UUID )
  • Bad programming practice.

Content

Data Signature

A magic number , or signature , is an integer or text constant used to uniquely identify a resource or data . Such a number in itself does not make any sense and can be bewildering if it is encountered in the program code without the appropriate context or comment , while trying to change it to another, even close in value, can lead to absolutely unpredictable consequences. For this reason, such numbers were ironically called magic . Currently, this name is firmly established as a term . For example, any compiled Java class starts with the hexadecimal magic number 0xCAFEBABE . The second widely known example is that any Microsoft Windows executable file with the .exe extension begins with a sequence of bytes 0x4D5A (which corresponds to the ASCII characters of MZ - the initials of Mark Zbikowski , one of the creators of MS-DOS ). A lesser-known example is the uninitialized pointer in Microsoft Visual C ++ (starting with the 2005 version of Microsoft Visual Studio), which in debug mode has the address 0xDEADBEEF .

On UNIX-like operating systems, the file type is usually determined by the signature of the file, regardless of the extension of its name. To interpret the file signature, they provide the standard file utility.

Bad programming practice

Also called "magic numbers" is bad programming practice when a numerical value is found in the source text and it is not obvious what it means. For example, such a fragment would be bad:

  drawSprite ( 53 , 320 , 240 );

It is difficult for a person who is not the author of the program to say what 53, 320 or 240 are. But if you rewrite this code, everything falls into place.

  final int SCREEN_WIDTH = 640 ;
 final int SCREEN_HEIGHT = 480 ;
 final int SCREEN_X_CENTER = SCREEN_WIDTH / 2 ;
 final int SCREEN_Y_CENTER = SCREEN_HEIGHT / 2 ;
 final int SPRITE_CROSSHAIR = 53 ;

 ...

 drawSprite ( SPRITE_CROSSHAIR , SCREEN_X_CENTER , SCREEN_Y_CENTER );

Now it’s clear: this line displays a sprite in the center of the screen - the crosshair of the sight. In most programming languages, all values ​​used for such constants will be calculated at the compilation stage and substituted in the place of use of the values. Therefore, such a change in the source text does not affect the performance of the program.

In addition, magic numbers are a potential source of program errors:

  • If the same magic number is used in the program more than once (or can potentially be used), then changing it will require editing each occurrence (instead of just editing the value of the named constant). If not all occurrences are corrected, at least one error will occur.
  • In at least one of the occurrences, a magic number may be spelled incorrectly from the beginning, and it is rather difficult to detect.
  • The magic number may depend on an implicit parameter or another magic number. If these dependencies, not explicitly identified, are not satisfied, at least one error will occur.
  • When modifying the occurrences of one magic number, you can mistakenly change another magic number, independent, but having the same numerical value.

Magic numbers and cross-platform

Sometimes magic numbers harm the cross-platform code [1] . The point is that in C , 32- and 64-bit OSs guarantee the size of char , short and long long types, while the sizes of int , long , size_t and ptrdiff_t can vary (for the first two, depending on the preferences of the compiler developers , in the last two - depending on the capacity of the target system). Old or unskilled code may contain “magic numbers” that mean the size of some type - when switching to machines with different bit depths, they can lead to subtle errors.

For example:

  const size_t NUMBER_OF_ELEMENTS = 10 ;

 long a [ NUMBER_OF_ELEMENTS ];

 memset ( a , 0 , 10 * 4 );  // wrong - implies that long is 4 bytes, the magic number of elements is used
 memset ( a , 0 , NUMBER_OF_ELEMENTS * 4 );  // wrong - implies that long is 4 bytes
 memset ( a , 0 , NUMBER_OF_ELEMENTS * sizeof ( long ));  // not quite right - duplication of the type name (if the type changes, you will have to change here too)
 memset ( a , 0 , NUMBER_OF_ELEMENTS * sizeof ( a [ 0 ]));  // correct, optimal for dynamic arrays of nonzero size
 memset ( a , 0 , sizeof ( a ));  // correct, optimal for static arrays

Numbers that are not magic

Not all numbers need to be transferred to constants. For example, the code in Delphi :

  for i : = 0 to Count - 1 do ...

The meaning of the numbers 0 and 1 is clear, and no further explanation is required.

See also

  • Hexspeak
  • Fast reverse square root

Notes

  1. ↑ 20 pitfalls of porting C ++ code to a 64-bit platform
Source - https://ru.wikipedia.org/w/index.php?title=Magic_number_ ( programming )&oldid = 99561833


More articles:

  • Guatemala at the 2016 Summer Olympics
  • Tsvetkov, Lev Nikolaevich
  • Zia-ul-Haq, Mohammed
  • Hongzvi, Chengherai
  • Karnaukh, Anna Olegovna
  • Soboleva, Evgenia Viktorovna
  • Jan Handric
  • Pavlova, Natalia V.
  • Premenstrual Syndrome
  • UEFA Junior Tournament 1963

All articles

Clever Geek | 2019