Magic number

Magic number

Magic number

En programmation informatique, le terme magic number (en français « nombre magique ») peut référer à :

  • une constante numérique ou un ensemble de caractères utilisé pour désigner un format de fichier ou un protocole ;
  • une constante numérique non-nommée ou non-documentée ;
  • un ensemble de valeurs ayant un sens particulier (par exemple, les GUID).

Sommaire

Indicateur de format

Origine

Ce type de magic number est apparu dans les premières versions du code source de la version 7 d'Unix (en). Bien qu'il ait perdu son sens originel, le terme a subsisté dans le lexique de l'informatique.

Quand Unix fut porté sur le premier DEC PDP-11/20s, celui-ci n'avait pas de mécanisme de protection de la mémoire (en) et utilisait des références mémoires re-allouables (en)[1]. Ainsi, les versions avant la version 6 d'Unix (en) lisent un fichier exécutable dans la mémoire en sautant à l'offset 0. Avec le développement de la pagination, les versions suivantes d'Unix ont vu le développement des headers précisant les composants d'un fichier exécutable. Une instruction de saut placée au début du header a été developpé pour permettre d'exécuter le programme directement (sans lire le header) ; ce qui permet de choisir entre exécuter le programme en utilisant l'ancien mode utilisant des références mémoires re-allouables (regular mode) ou en passant par la pagination. Avec le développement des formats d'exécutables, de nouvelles constantes de saut ont été ajoutées en incrémentant l'offset[2].

Dans le Lions' Commentary on UNIX 6th Edition, with Source Code (en) de la version 6 d'Unix, la fonction exec() lit l'image binaire d'un exécutable à partir du système de fichier. Les huit premiers octets forment le header qui contient la taille du programme (segment text) et les variables initialisées (segment global). Le premier mot de seize bits de ce header est comparé à deux constantes pour déterminer si l'exécutable utilise des références mémoires re-allouables, le système de page en lecture seul récemment développé ou des pages séparées pour les instructions et les données[3]. Dans la sixième et la septième version d'Unix, le double rôle de cette constante du début du header n'était pas précisé mais le bit de poids fort de cette constant était l'opcode de l'instruction de saut sur un PDP-11 (octal 000407 ou hex 0107). Si on ajoute sept au compteur de programme d'un programme exécuté, celui-ci va utiliser le service exec() pour se lancer.

Le service exec() lit le header du fichier exécutable (méta) depuis un buffer de l'espace noyau mais l'image exécutable est lut dans l'espace utilisateur et donc sans pouvoir utiliser la constante de saut. Les magic number ont alors été implémenté dans l'éditeur de liens et le chargeur d'Unix ; ils ont du être utilisé par la suite dans les programmes de test livrés avec la version 6 et 7 d'Unix.

Dans la version 7, la constante n'est pas lu directement ; elle est d'abord assignée à la variable ux_mag[4] et fut par la suite désigné par l'expression magic number. Sachant qu'il y avait alors dans cet Unix environ 10 000 lignes de code et beaucoup de constantes utilisées, ce nom est plustôt curieux pour une constante, au moins autant que le commentaire[1] laissé dans la partie concernant le changement de contexte de la version 6 du gestionnaire d'applications d'Unix. C'est probablement pour cela que le terme a ensuite désigné le type d'exécutable, puis étendu aux systèmes de fichiers et étendu encore pour désigner un exécutable utilisant un typage fort.

Dans les fichiers

Exemples

Détection

Dans les protocoles

Constante numérique innommée

Le terme de magic number peut également correspondre à l'utilisation de constantes numériques innomées directement dans le code source d'un programme. L'utilisation de constantes numériques innomées dans le code source est la plupart du temps source d'erreur, et rend plus difficile l'adaptation ou la compréhension future d'un programme. Le nommage de tous les magic number rend le code plus lisible, plus compréhensible et plus facilement maintenable.

Les noms de constante choisis doivent avoir du sens dans le contexte précis.

Les problèmes avec les magic number décrits plus haut ne se limitent pas au constantes numériques, le terme est également utilisé pour d'autre type de données, la déclaration des constantes étant plus flexible et plus communicatif. Par exemple, déclarer const string testNomUtilisateur = "Jean" est meilleur que plusieurs occurrences du magic number "Jean" dans une suite de tests.

Par exemple, si il est nécessaire de mélanger aléatoirement les valeurs d'un tableau contenant les valeurs d'un jeu de 52 cartes, le pseudo code suivant le permettrait:

   for i from 1 to 52
       j := i + randomInt(53 - i) - 1
       a.swapEntries(i, j)

a est un objet de type tableau, la fonction randomInt(x) choisi un chiffre au hasard entre 1 et x compris, et swapEntries(i, j) échange la position des données placées en i et j dans le tableau. Dans l'exemple précédent, 52 est un magic number. Il est conseillé de plutôt écrire:

   constant int nombreDeCarte := 52
   for i from 1 to nombreDeCarte
       j := i + randomInt(nombreDeCarte + 1 - i) - 1
       a.swapEntries(i, j)

Ceci est préférable pour plusieurs raisons:

  • Le second exemple est plus facile à lire et à comprendre. Un développeur lisant pour le premier exemple se demanderait A quoi correspond le nombre 52? Pourquoi 52. Il serait certainement capable de comprendre la signification du 52 après la lecture du code complet, mais ce n'est pas simple. Les magic number deviennent particulièrement déroutant lorsque la même valeur est utilisé pour plusieurs signification dans une même partie de code.
  • Il est plus simple de modifier la valeur de la constante dans le second exemple car celle-ci n'est pas dupliquée. Changer la valeur d'un magic number est source d'erreur, car la même valeur est très souvent utilisé plusieurs fois dans le même programme. Il se peut également, dans le cas où deux variables aux significations différentes ont la même valeur, qu'elle soient toutes deux modifiées accidentellement. Pour modifier le premier exemple afin de mélanger un jeu de tarot, qui contient 78 cartes, le développeur pourrait remplacer naïvement toutes les instances de 52 dans le programme par 78. Cela pourrait causer deux problèmes. Premièrement, la valeur 53 de la seconde ligne de l'exemple ne sera pas modifiée, ce qui ammènera le programme à ne traiter qu'une partie des cartes. Deuxièmement, il se peut qu'il remplace la chaîne "52" dans tout le programme sans prêter attention à ce qu'elle signifie, le nombre de cartes ou totalement autre chose, ce qui introduirait très certainement des bugs. Par comparaison, changer la valeur de nombreDeCarte dans le second exemple est une opération très simple et ne nécessite la modification que d'une seule ligne.
  • La déclaration des variables remplaçant les magic number sont généralement placée ensemble, au début des fonctions ou fichier. Ceci facilite leur recherche et leur modification.
  • La mise est paramètre est également plus aisée. Par exemple, pour transformer l'exemple ci-dessus en une procédure qui mélange un tas de carte, il sera aisé de passer nombreDeCarte en paramètre de la procédure. Le premier exemple nécessitera quant à lui plusieurs modifications, comme suit:

function melange(int nombreDeCarte )

      for i from 1 to nombreDeCarte 
          j := i + randomInt(nombreDeCarte + 1 - i) - 1
          a.swapEntries(i, j)
  • Il est également plus facile de détecter les erreurs de frappe. En utilisant une variable déclarée en lieu et place d'un literal permet l'utilisation de la vérification par le compilateur. Par exemple, saisir "62" au lieu de "52" ne sera pas détecté alors que "nombedeCarte" au lieu de "nombreDeCarte" lèvera un warning (ou une erreur) du compilateur nous informant que "nombeDeCarte" est indéfini.
  • Cela permet également de minimiser les saisies au clavier dans certain IDE. Si l'IDE permet le complètement automatique, il suffira de saisir les premières lettres de la variable pour que l'IDE le complète automatiquement.


Incovénients:

  • Sur certain CPU, l'exécution de l'expression nombreDeCarte + 1 prendra plus de temps que l'expression 53. Néanmoins, la plupart des compileurs et interpreteurs moderne sont capable de comprendre que la variable nombreDeCarte a été déclarée comme constante et pre-calcule la valeur 53 dans le code compilé. Il n'y a donc aucun gain de temps à utiliser des magic number.
  • L'utilisation de variables déclarée allonge les lignes de code, obligeant les lignes de code à s'étaler sur plusieurs lignes si plusieurs constantes sont utilisés sur la même ligne.

Usages acceptés comme constantes numériques non-nommées

Dans certain cas, l'utilisation de constantes numériques non-nommées est acceptée. Ces utilisations correctes étant subjectives, et dépendantes des habitudes de codage, les exemple suivant sont des exemples communs:

  • l'utilisation du 0 ou du 1 comme valeur initiale ou valeur d'incrémentation dans les boucle for telle que for (int i=0;i<max;i=i+1) (en prenant comme hypothèse que i++ n'est pas supporté)
  • l'utilisation de 2 dans les expressions telles que périmètre = rayon * Math.PI * 2
  • l'utilisation de 2 pour vérifier qu'un nombre est pair ou impair bool estPair = (x%2==0), où % est l'opérateur modulo

Les constantes 1 et 0 sont parfois utilisées pour représentes les valeurs booléens True et False dans les langages de programmation sans type boolean comme les anciennes version de C. La plupart des languages modernes contiennent les types boolean ou bool, l'usage de 0 ou 1 dans ce cas là est proscrite.

En C ou C++, 0 est parfois utilisé pour représenter le null pointer ou reference. Comme pour les valeurs booléens, les librairies de C standards contiennent des macro définitions de NULL dont l'utilisation est fortement conseillée. D'autre langages proposent des valeurs null ou nil spécifiques et dans ce cas, aucune autre alternative ne devrait être utilisé.

Magics GUIDs

Il est possible de créer ou modifier des GUID pour qu'il soit facilement mémorisables bien que cela pussi affecter leur efficacité eet leur unicité[5]. Les règles pour générer des GUID et des UUID sont complexes mais assurent d'avoir des numéros uniques si elles sont suivi scrupuleusement.

Plusieurs GUID java commencent par « CAFEEFAC ».

Magic number de débogage

Certains magic number ont une valeur particulière qui est écrite dans la mémoire vive pendant l'allocation dynamique (en) ou la ré-allocation pour permettre un debugage en cas de plantage. Pendant le débugage, la mémoire est généralement affichée en héxadécimal où des codes répétitifs ou en Hexspeak (en) sont facilement reconnaissables.

Ces valeurs sont utilisées de préférence sur des processeurs sans bit d'adressage car ceux-ci planterons s'ils essaient de les utiliser comme pointeur.

Vu qu'il soit rare qu'un entier codé sur 32 bit prenne une de ses valeurs, le passage d'un de ces nombres dans un debbugeur ou un core dump (en) indique généralemnt un dépassement de tampon ou une variable non initialisée.

Valeurs classiques
Code Description
..FACADE Utilisé par beaucoup de systèmes d'exploitation temps réel
8BADF00D Utilisé par Apple comme code d'exception dans l'iPhone quand une application a pris trop de temps pour se lancer ou se terminer
A5A5A5A5 Utilisé sur les systèmes embarqués car la séquence binaire correspondante (10100101) est facilement reconnaissable sur un oscilloscope ou un analyseur logique
ABABABAB Utilisé par la fonction HeapAlloc() de Microsoft pour marquer le « no man's land » d'un Guard byte (en) après l'allocation de la mémoire heap
ABADBABE Utilisé par Apple comme « Boot Zero Block »
ABADCAFE Valeur d'initialisation utilisée pour démasquer les pointeurs brisés
BAADF00D Utilisé par la fonction LocalAlloc(LMEM_FIXED) de Microsoft pour marquer la mémoire heap allouée mais non initialisée
BADBADBADBAD Utilisé sur les calculateurs de Burroughs Corporation pour repérer la mémoire non-initialisée (mot de 48-bit)
BADC0FFEE0DDF00D Utilisé sur le système 64 bits RS/6000 pour indiquer les registres processeurs non-initialisés
BADCAB1E Code d'erreur retourné par le debuggeur eVC quand la connection avec le débuggeur est coupée
BADDCAFE Sous Solaris, marque la mémoire du noyau qui n'est pas initialisée (KMEM_UNINITIALIZED_PATTERN)
BEEFCACE Utilisé sur le framework .NET comme nombre magique pour les fichiers de ressources (en)
C0DEDBAD
CAFEBABE Dans les exécutables Mach-O (Fat binary (en) dans les processeurs 68k et les PowerPC) pour identifier les fichier objet et les .class java
CAFEFEED Sous Solaris, marque le mémoire allouée par la fonction kmemfree() pour le debugage
CCCCCCCC Utilisé par la libraire de debugage du C++ de Microsoft pour repérer la mémoire stack non-initialisée
CDCDCDCD Utilisé par la libraire de debugage du C++ de Microsoft pour repérer la mémoire heap non-initialisée
CEFAEDFE Peut-être vu dans les binaires Mach-O de Mac OS X (voir FEEDFACE)
DDDDDDDD Utilisé par MicroQuill's SmartHeap et le débuggeur mémoire C++ de Microsoft pour marquer la mémoire heap libérée
DEADBABE Marque le début des fichiers arena d'IRIX
DEADBEEF Connu pour être utilisé sur les systèmes IBM (notamment sur RS/6000), le premier Mac OS (OPENSTEP) et sur le Commodore Amiga. Sous Solaris, marque la mémoire du noyau libérée (KMEM_FREE_PATTERN)
DEADDEAD Le code d'erreur STOP de Windows utilisé quand l'utilisateur crash volontairement la machine
DEADF00D Marque toutes les nouvelles zones mémoire allouées quand elle n'ont pas été explicitement nettoyées après une corruption
DEADFA11 Utilisé par Apple comme code d'exception dans l'iPhone quand l'utilisateur a forcé une application à s'éteindre
EBEBEBEB Pour MicroQuill's SmartHeap
FADEDEAD Marque le fin des scripts AppleScript
FDFDFDFD Utilisé par le débuggeur mémoire C++ de Microsoft pour marquer le « no man's land » d'un Guard byte (en) avant et après la mémoire heap allouée
FEE1DEAD Utilisé par l'appel système reboot() de Linux
FEEDFACE Peut-être vu sur le binaires PowerPC Mach-O de Mac OS X. Sous Solaris, marque la zone rouge (KMEM_REDZONE_PATTERN)
FEEEFEEE Utilisé par la fonction HeapFree() de Microsoft pour marquer la mémoire heap libérée

Notes et références

  1. a  et b Odd Comments and Strange Doings in Unix [1]
  2. Personal communication with Dennis M. Ritchie
  3. Version six system1 source file [2]
  4. Version seven system1 source file [3]
  5. (en) Joseph M. Newcomer, « Message Management - Guaranteeing uniqueness ». Mis en ligne le 13 octobre 2001, consulté le 6 septembre 2009
  • Portail de la programmation informatique Portail de la programmation informatique
Ce document provient de « Magic number ».

Wikimedia Foundation. 2010.

Contenu soumis à la licence CC-BY-SA. Source : Article Magic number de Wikipédia en français (auteurs)

Игры ⚽ Поможем решить контрольную работу

Regardez d'autres dictionnaires:

  • Magic number — may refer to: Magic number (chemistry), number of atoms or molecules forming an exceptionally stable cluster Magic number (sports), a number that indicates how close a team is to winning a season title Magic number (oil), the price per barrel of… …   Wikipedia

  • magic number — noun singular a number that is important or has to be reached before something can happen: The magic number of 65 is needed for a majority …   Usage of the words and phrases in modern English

  • magic number — UK / US noun [singular] a number that is important or has to be reached before something can happen The magic number of 65 is needed for a majority …   English dictionary

  • magic number — magiškasis skaičius statusas T sritis Standartizacija ir metrologija apibrėžtis Magiškojo branduolio protonų arba neutronų skaičius. atitikmenys: angl. magic number vok. magische Zahl, f rus. магическое число, n pranc. nombre magique, m …   Penkiakalbis aiškinamasis metrologijos terminų žodynas

  • magic number — magiškasis skaičius statusas T sritis fizika atitikmenys: angl. magic number vok. magische Zahl, f rus. магическое число, n pranc. nombre magique, m …   Fizikos terminų žodynas

  • Magic Number (Maaya Sakamoto song) — Magic Number Single by Maaya Sakamoto B side Private Sky Released November 11, 2009 Format CD Recorded 2 …   Wikipedia

  • Magic Number (pricing game) — Magic # is a pricing game on the American television game show The Price Is Right . Debuting on the Season 21 premiere on September 14, 1992, it is played for two prizes, each worth at least $1,000.GameplayTwo prizes are shown, and the contestant …   Wikipedia

  • Magic number (programming) — For other uses of the term, see Magic number (disambiguation). In computer programming, the term magic number has multiple meanings. It could refer to one or more of the following: A constant numerical or text value used to identify a file format …   Wikipedia

  • Magic number (sports) — For other uses of the term, see Magic number (disambiguation). In certain sports, a magic number is a number used to indicate how close a front running team is to clinching a season title. It represents the total of additional wins by the front… …   Wikipedia

  • Magic number (physics) — Graph of isotope stability. In nuclear physics, a magic number is a number of nucleons (either protons or neutrons) such that they are arranged into complete shells within the atomic nucleus. The seven most widely recognised magic numbers as of… …   Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”