stringtranslate.com

Número mágico (programación)

En programación informática , un número mágico es cualquiera de los siguientes:

Constantes numéricas sin nombre

El término número mágico o constante mágica se refiere al antipatrón de usar números directamente en el código fuente. Esto se ha considerado como una violación de una de las reglas más antiguas de la programación, que se remonta a los manuales COBOL , FORTRAN y PL/1 de la década de 1960. [1] El uso de números mágicos sin nombre en el código oscurece la intención de los desarrolladores al elegir ese número, [2] aumenta las oportunidades de errores sutiles (por ejemplo, ¿es correcto cada dígito en 3.14159265358979323846 y se puede redondear a 3.14159? [3] ) y hace que sea más difícil que el programa se adapte y amplíe en el futuro. [4] Reemplazar todos los números mágicos significativos con constantes con nombre (también llamadas variables explicativas) hace que los programas sean más fáciles de leer, comprender y mantener. [5]

Los nombres elegidos para que tengan significado en el contexto del programa pueden dar como resultado un código que sea más fácil de entender para un mantenedor que no sea el autor original (o incluso para el autor original después de un período de tiempo). [6] Un ejemplo de una constante con un nombre poco informativo es int SIXTEEN = 16, mientras que int NUMBER_OF_BITS = 16es más descriptivo.

Los problemas asociados con los 'números' mágicos descritos anteriormente no se limitan a los tipos numéricos y el término también se aplica a otros tipos de datos donde declarar una constante nombrada sería más flexible y comunicativo. [1] Por lo tanto, declarar const string testUserName = "John"es mejor que varias apariciones del 'valor mágico' "John"en un conjunto de pruebas .

Por ejemplo, si se requiere mezclar aleatoriamente los valores de una matriz que representa una baraja de cartas estándar , este pseudocódigo hace el trabajo utilizando el algoritmo de mezcla de Fisher-Yates :

para i del 1 al 52 j := i + int aleatorio (53 - i) - 1 a.swapEntries(i, j)

donde aes un objeto de matriz, la función randomInt(x)elige un entero aleatorio entre 1 y x , ambos inclusive, e swapEntries(i, j)intercambia las entradas i y j52 de la matriz. En el ejemplo anterior, es un número mágico. Se considera que es un mejor estilo de programación escribir lo siguiente:

int deckSize:= 52 para i desde 1 hasta deckSize j := i + randomInt(tamañoBaraja + 1 - i) - 1 a.swapEntries(i, j)

Esto es preferible por varias razones:

función shuffle ( int deckSize) para i desde 1 hasta deckSize j := i + randomInt(tamañoBaraja + 1 - i) - 1 a.swapEntries(i, j)

Las desventajas son:

Usos aceptados

En algunos contextos, el uso de constantes numéricas sin nombre es generalmente aceptado (y posiblemente "no sea mágico"). Si bien dicha aceptación es subjetiva y a menudo depende de los hábitos de codificación individuales, los siguientes son ejemplos comunes:

Las constantes 1 y 0 se utilizan a veces para representar los valores booleanos true y false en lenguajes de programación sin un tipo booleano, como las versiones anteriores de C. La mayoría de los lenguajes de programación modernos proporcionan un tipo primitivoboolean o , por lo que el uso de 0 y 1 no es recomendable. Esto puede ser más confuso ya que 0 a veces significa éxito programático (cuando -1 significa fracaso) y fracaso en otros casos (cuando 1 significa éxito).bool

En C y C++, 0 representa el puntero nulo . Al igual que con los valores booleanos, la biblioteca estándar de C incluye una definición de macro NULLcuyo uso se recomienda. Otros lenguajes proporcionan un valor nullor específico nily, cuando este es el caso, no se debe utilizar ninguna alternativa. La constante de puntero tipado nullptrse introdujo con C++11.

Indicadores de formato

Origen

Los indicadores de formato se utilizaron por primera vez en el código fuente de Unix de la versión 7. [ cita requerida ]

Unix fue portado a uno de los primeros DEC PDP-11 /20, que no tenía protección de memoria . Por lo tanto, las primeras versiones de Unix usaban el modelo de referencia de memoria reubicable . [7] Las versiones de Unix anteriores a la Sexta Edición leían un archivo ejecutable en la memoria y saltaban a la primera dirección de memoria baja del programa, la dirección relativa cero. Con el desarrollo de versiones paginadas de Unix, se creó un encabezado para describir los componentes de la imagen ejecutable . Además, se insertó una instrucción de bifurcación como la primera palabra del encabezado para omitir el encabezado e iniciar el programa. De esta manera, un programa podía ejecutarse en el antiguo modo de referencia de memoria reubicable (regular) o en modo paginado. A medida que se desarrollaron más formatos ejecutables, se agregaron nuevas constantes incrementando el desplazamiento de la bifurcación . [8]

En el código fuente de la sexta edición del cargador de programas de Unix, la función exec() leía la imagen ejecutable ( binaria ) del sistema de archivos. Los primeros 8 bytes del archivo eran un encabezado que contenía los tamaños del programa (texto) y las áreas de datos inicializadas (globales). Además, la primera palabra de 16 bits del encabezado se comparaba con dos constantes para determinar si la imagen ejecutable contenía referencias de memoria reubicables (normal), la imagen ejecutable de solo lectura paginada recientemente implementada o la imagen paginada de instrucciones y datos separados. [9] No se mencionaba el papel dual de la constante del encabezado, pero el byte de orden alto de la constante era, de hecho, el código de operación para la instrucción de bifurcación PDP-11 ( octal 000407 o hexadecimal 0107). Agregar siete al contador del programa mostraba que si se ejecutaba esta constante , ramificaría el servicio exec() de Unix sobre el encabezado de ocho bytes de la imagen ejecutable e iniciaría el programa.

Dado que la sexta y séptima ediciones de Unix empleaban código de paginación, el doble papel de la constante de encabezado estaba oculto. Es decir, el servicio exec() leía los datos de encabezado del archivo ejecutable ( meta ) en un búfer de espacio del núcleo , pero leía la imagen ejecutable en el espacio del usuario , por lo que no utilizaba la característica de ramificación de la constante. La creación de números mágicos se implementó en el enlazador y cargador de Unix y la ramificación de números mágicos probablemente todavía se usaba en el conjunto de programas de diagnóstico independientes que venían con la sexta y séptima ediciones. Por lo tanto, la constante de encabezado proporcionaba una ilusión y cumplía los criterios para ser mágica .

En la versión siete de Unix, la constante de encabezado no se probaba directamente, sino que se asignaba a una variable denominada ux_mag [10] y, posteriormente, se la denominaba número mágico . Probablemente debido a su singularidad, el término número mágico pasó a significar tipo de formato ejecutable, luego se expandió para significar tipo de sistema de archivos y se expandió nuevamente para significar cualquier tipo de archivo.

En archivos

Los números mágicos son comunes en programas de muchos sistemas operativos. Los números mágicos implementan datos fuertemente tipados y son una forma de señalización en banda para el programa de control que lee los tipos de datos en tiempo de ejecución del programa. Muchos archivos tienen constantes de este tipo que identifican los datos que contienen. Detectar dichas constantes en los archivos es una forma simple y efectiva de distinguir entre muchos formatos de archivo y puede brindar más información en tiempo de ejecución .

Ejemplos
Detección

El programa de utilidad de Unix filepuede leer e interpretar números mágicos de archivos, y el archivo que se utiliza para analizar la información se llama magic . La utilidad de Windows TrID tiene una finalidad similar.

En protocolos

Ejemplos

En interfaces

Los números mágicos son comunes en las funciones e interfaces de API en muchos sistemas operativos , incluidos DOS , Windows y NetWare :

Ejemplos

Otros usos

Ejemplos

Límites de tipos de datos

Esta es una lista de límites de los tipos de almacenamiento de datos: [16]

GUID

Es posible crear o alterar identificadores únicos globales (GUID) para que sean memorables, pero esto se desaconseja enfáticamente ya que compromete su fortaleza como identificadores casi únicos. [17] [18] Las especificaciones para generar GUID y UUID son bastante complejas, lo que lleva a que sean virtualmente únicos, si se implementan correctamente. [19]

Los números de identificación de producto de Microsoft Windows para productos de Microsoft Office a veces terminan con 0000-0000-0000000FF1CE("OFFICE"), como { 90160000-008C-0000-0000-0000000FF1CE}, el identificador de producto para el "Componente de extensibilidad de hacer clic y ejecutar de Office 16".

Java utiliza varios GUID que comienzan con CAFEEFAC. [20]

En la tabla de particiones GUID del esquema de particionamiento GPT, las particiones de arranque del BIOS utilizan el GUID especial { 21686148-6449-6E6F-744E-656564454649} [21] que no sigue la definición de GUID; en su lugar, se forma utilizando los códigos ASCIIHah!IdontNeedEFI para la cadena " " parcialmente en orden little endian . [22]

Valores de depuración

Los valores de depuración mágicos son valores específicos que se escriben en la memoria durante la asignación o desasignación, de modo que más tarde sea posible saber si se han corrompido o no, y para que sea obvio cuando se están utilizando valores tomados de la memoria no inicializada. La memoria suele verse en hexadecimal, por lo que es común recordar valores repetidos o en lenguaje hexadecimal . Se pueden preferir valores numéricamente impares para que los procesadores sin direccionamiento de bytes fallen al intentar usarlos como punteros (que deben caer en direcciones pares). Se deben elegir valores que estén lejos de las direcciones probables (el código del programa, los datos estáticos, los datos del montón o la pila). De manera similar, se pueden elegir de modo que no sean códigos válidos en el conjunto de instrucciones para la arquitectura dada.

Dado que es muy poco probable, aunque posible, que un entero de 32 bits tome este valor específico, la aparición de dicho número en un depurador o en un volcado de memoria probablemente indique un error, como un desbordamiento de búfer o una variable no inicializada .

Algunos ejemplos famosos y comunes incluyen:

La mayoría de estos tienen una longitud de 32 bits : el tamaño de palabra de la mayoría de las computadoras con arquitectura de 32 bits.

La prevalencia de estos valores en la tecnología de Microsoft no es casualidad; se analizan en detalle en el libro de Steve Maguire Writing Solid Code de Microsoft Press . En él, Maguire ofrece una variedad de criterios para estos valores, como:

Dado que a menudo se utilizaban para marcar áreas de memoria que estaban esencialmente vacías, algunos de estos términos llegaron a utilizarse en frases que significaban "desaparecido, abortado, borrado de la memoria"; por ejemplo, "Su programa está MUERTO". [ cita requerida ]

Véase también

Referencias

  1. ^ abc Martin, Robert C. (2009). "Capítulo 17: Olores y heurísticas - G25 Reemplazar números mágicos por constantes nombradas". Clean Code - A handbook of agile software craftsmanship . Boston: Prentice Hall. pág. 300. ISBN 978-0-13-235088-4.
  2. ^ Martin, Robert C. (2009). "Capítulo 17: Olores y heurísticas - G16 Obscured Intent". Clean Code - A handbook of agile software craftsmanship . Boston: Prentice Hall. pág. 295. ISBN 978-0-13-235088-4.
  3. ^ Contieri, Maxi (2020-10-20). "Code Smell 02 - Constantes y números mágicos". Maximiliano Contieri - Diseño de software . Consultado el 21 de marzo de 2024 .
  4. ^ Maguire, James (9 de diciembre de 2008). "Bjarne Stroustrup sobre la educación de los desarrolladores de software". Datamation.com . Archivado desde el original el 23 de junio de 2018.
  5. ^ Vogel, Jeff (29 de mayo de 2007). "Seis maneras de escribir código más comprensible". IBM Developer . Archivado desde el original el 26 de septiembre de 2018.
  6. ^ abcdef Paul, Matthias R. (9 de abril de 2002). «[fd-dev] CuteMouse 2.0 alpha 1». freedos-dev . Archivado desde el original el 7 de abril de 2022 . Consultado el 4 de agosto de 2022 .
  7. ^ "Comentarios extraños y hechos extraños en Unix". Bell Labs . 22 de junio de 2002. Archivado desde el original el 4 de noviembre de 2006.
  8. ^ Comunicación personal con Dennis M. Ritchie.
  9. ^ "El árbol Unix V6/usr/sys/ken/sys1.c". The Unix Heritage Society . Archivado desde el original el 26 de marzo de 2023.
  10. ^ "El árbol Unix V7/usr/sys/sys/sys1.c". The Unix Heritage Society . Archivado desde el original el 26 de marzo de 2023.
  11. ^ "Especificación PNG (Portable Network Graphics) Versión 1.0: 12.11. Firma del archivo PNG". MIT . 1996-10-01. Archivado desde el original el 2023-03-26.
  12. ^ Chen, Raymond (24 de marzo de 2008). "¿Cuál es la diferencia entre las extensiones COM y EXE?". The Old New Thing . Archivado desde el original el 18 de febrero de 2019.
  13. ^ abc Paul, Matthias R. (3 de abril de 2002). «[fd-dev] Ctrl+Alt+Del». freedos-dev . Archivado desde el original el 9 de septiembre de 2017 . Consultado el 9 de septiembre de 2017 .(NB. Menciona una serie de valores mágicos utilizados por BIOS compatibles con IBM PC (0000h, 1234h), administradores de memoria DOS como EMM386 (1234h) y cachés de disco como SMARTDRV (EBABh, BABEh) y NWCACHE (0EDCh, EBABh, 6756h).)
  14. ^ "El proceso de arranque del BIOS/MBR". Base de conocimiento de NeoSmart . 2015-01-25. Archivado desde el original el 2023-03-26 . Consultado el 2019-02-03 .
  15. ^ "Comunidad TI E2E: ¿Alguien sabe si las siguientes configuraciones se pueden realizar con la herramienta MCP CLI?". Texas Instruments . 2011-08-27. Archivado desde el original el 2022-10-07.
  16. ^ Poley, Josh (30 de septiembre de 2009). "Números mágicos: números enteros". Learn . Microsoft . Archivado desde el original el 28 de marzo de 2023.
  17. ^ Newcomer, Joseph M. (13 de octubre de 2001). "Gestión de mensajes: garantizar la unicidad". Developer Fusion . Archivado desde el original el 21 de abril de 2005. Consultado el 16 de noviembre de 2007 .
  18. ^ Osterman, Larry (21 de julio de 2005). "Los UUID solo son únicos si los generas..." Larry Osterman's WebLog - Confessions of an Old Fogey (Blog web de Larry Osterman: confesiones de un viejo cascarrabias ). MSDN. Archivado desde el original el 28 de marzo de 2023. Consultado el 16 de noviembre de 2007 .
  19. ^ "RFC 9562 - Identificadores universalmente únicos (UUID)". ietf.org . Mayo de 2024 . Consultado el 9 de agosto de 2024 .
  20. ^ "Implementación de subprogramas Java con versiones de la familia JRE en el complemento Java para Internet Explorer". Oracle . Archivado desde el original el 2022-11-30 . Consultado el 2023-03-28 .
  21. ^ "Instalación de GNU GRUB, Sección 3.4: Instalación del BIOS". Gnu.org . Archivado desde el original el 2023-03-15 . Consultado el 2014-06-26 .
  22. ^ Heddings, Lowell (3 de noviembre de 2014). «Números mágicos: los códigos secretos que los programadores ocultan en su PC». How-To Geek . Archivado desde el original el 26 de marzo de 2023. Consultado el 3 de octubre de 2017 .
  23. ^ Cavit, Doug (24 de abril de 2012). "Protección contra la reutilización de referencias a objetos obsoletos". Microsoft Secure . Archivado desde el original el 26 de julio de 2018. Consultado el 26 de julio de 2018 .
  24. ^ Boleyn, Erich Stefan (4 de abril de 1995). "Comentarios sobre la propuesta del 'estándar MultiBoot'". Uruk.org . Archivado desde el original el 26 de marzo de 2023.
  25. ^ abcdef "Nota técnica TN2151: Comprensión y análisis de los informes de fallos de las aplicaciones". Documentación para desarrolladores de Apple . 29 de enero de 2009. Archivado desde el original el 13 de diciembre de 2018.
  26. ^ abcdef Birkett, Andrew. "Componentes internos del montón CRT de depuración de Win32". Nobugs.org .
  27. ^ McNamara, Paul (19 de julio de 2012). "El código de Microsoft contiene la frase 'grandes tetas'... Sí, de verdad". Network World .
  28. ^ WebKit, The WebKit Open Source Project, 6 de enero de 2023 , consultado el 6 de enero de 2023
  29. ^ "AddressSanitizer - Preguntas frecuentes". GitHub . Consultado el 18 de mayo de 2022 .
  30. ^ "MANUAL DE REFERENCIA DEL PROGRAMADOR INTEL 80386". MIT .
  31. ^ Scheppner, Carolyn. "Guía de Amiga Mail Vol.2". Cataclysm.cx . Archivado desde el original el 18 de julio de 2011. Consultado el 20 de agosto de 2010 .
  32. ^ "Comprobación de error 0xDEADDEAD MANUALLY_INITIATED_CRASH1". Documentación de Microsoft . 19 de junio de 2023.
  33. ^ "La versión 14.0.1 de Safari se cierra inesperadamente".
  34. ^ "strncat_s, _strncat_s_l, wcsncat_s, _wcsncat_s_l, _mbsncat_s, _mbsncat_s_l". Documentación de Microsoft . Consultado el 16 de enero de 2019 .