stringtranslate.com

Número mágico (programación)

En programación de computadoras , 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. Se ha dicho que esto es romper una de las reglas de programación más antiguas, 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 es igual a 3.14159? [3] ) y hace 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 sean significativos 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 no informativo es int SIXTEEN = 16, aunque 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 con nombre 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 es necesario barajar aleatoriamente los valores en una matriz que representa una baraja de naipes estándar , este pseudocódigo hace el trabajo utilizando el algoritmo de barajado de Fisher-Yates :

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

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

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

Esto es preferible por varias razones:

función aleatoria ( int deckSize) para i de 1 a deckSize j := i + randomInt(tamañodecubierta + 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 es 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 Verdadero y Falso 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 no se recomienda el uso de 0 y 1. Esto puede resultar 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 específico nully nilcuando este es el caso no se debe utilizar ninguna alternativa. La constante de puntero escrita 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 anterior . [ cita necesaria ]

Unix fue portado a uno de los primeros DEC PDP-11 /20, que no tenía protección de memoria . Por eso, las primeras versiones de Unix utilizaban el modelo de referencia de memoria reubicable . [7] Las versiones Unix anteriores a la sexta edición leen un archivo ejecutable en la memoria y saltan 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 primera palabra del encabezado para omitir el encabezado e iniciar el programa. De esta manera, un programa podría ejecutarse en el modo (normal) de referencia de memoria reubicable anterior o en modo paginado. A medida que se desarrollaron más formatos ejecutables, se agregaron nuevas constantes incrementando el desplazamiento de la rama . [8]

En el código fuente de la sexta edición del cargador de programas Unix, la función exec() lee 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 comparó con dos constantes para determinar si la imagen ejecutable contenía referencias de memoria reubicables (normal), la imagen ejecutable paginada de solo lectura recién implementada o la imagen paginada de instrucciones y datos separados. [9] No se mencionó la doble función de la constante de encabezado, pero el byte de orden superior 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 mostró que si se ejecutaba esta constante , bifurcaría el servicio Unix exec() 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, la doble función de la constante de encabezado estaba oculta. Es decir, el servicio exec() lee los datos del encabezado ( meta ) del archivo ejecutable en un búfer de espacio del kernel , pero lee la imagen ejecutable en el espacio del usuario , por lo que no utiliza la función 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 las ediciones sexta y séptima. Por lo tanto, la constante del encabezado proporcionó una ilusión y cumplió con los criterios de magia .

En la versión siete de Unix, la constante del encabezado no se probó directamente, sino que se asignó a una variable denominada ux_mag [10] y posteriormente se la denominó 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 dentro de banda para el programa de control que lee los tipos de datos en tiempo de ejecución del programa. Muchos archivos tienen constantes que identifican los datos contenidos. Detectar dichas constantes en archivos es una forma sencilla y eficaz de distinguir entre muchos formatos de archivos y puede proporcionar más información en tiempo de ejecución .

Ejemplos
Detección

El programa de utilidad 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 TrID de Windows tiene un propósito similar.

En protocolos

Ejemplos

En interfaces

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

Ejemplos

Otros usos

Ejemplos

Límites de tipo 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 globalmente (GUID) para que sean memorables, pero esto se desaconseja porque compromete su fuerza como identificadores casi únicos. [17] [18] Las especificaciones para generar GUID y UUID son bastante complejas, lo que los lleva a ser prácticamente únicos, si se implementan correctamente. . [ cita necesaria ]

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

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

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

Valores de depuración

Los valores de depuración mágica son valores específicos escritos en la memoria durante la asignación o desasignación, de modo que luego será posible saber si se han dañado o no y hacer obvio cuándo se están utilizando valores tomados de la memoria no inicializada. La memoria generalmente se ve en hexadecimal, por lo que son comunes los valores repetidos o de jerga hexadecimal memorables . 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 alejados de direcciones probables (el código del programa, datos estáticos, datos del montón o la pila). De manera similar, se pueden elegir de manera 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 volcado de memoria probablemente indique un error como un desbordamiento del búfer o una variable no inicializada .

Ejemplos famosos y comunes incluyen:

La mayoría de ellos tienen una longitud de 32 bits cada uno , 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 una coincidencia; se analizan en detalle en el libro de Steve Maguire Writing Solid Code de Microsoft Press . Da una variedad de criterios para estos valores, tales como:

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

Ver también

Referencias

  1. ^ abc Martín, Robert C. (2009). "Capítulo 17: Olores y heurística - G25 Reemplazar números mágicos con constantes con nombre". Código limpio: un manual de artesanía en software ágil . Boston: Prentice Hall. pag. 300.ISBN​ 978-0-13-235088-4.
  2. ^ Martín, Robert C. (2009). "Capítulo 17: Olores y heurística - Intención oscurecida G16". Código limpio: un manual de artesanía en software ágil . Boston: Prentice Hall. pag. 295.ISBN 978-0-13-235088-4.
  3. ^ Contieri, Maxi (20 de octubre de 2020). "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 formación de desarrolladores de software". Datamation.com . Archivado desde el original el 23 de junio de 2018.
  5. ^ Vogel, Jeff (29 de mayo de 2007). "Seis formas de escribir código más comprensible". Desarrollador IBM . Archivado desde el original el 26 de septiembre de 2018.
  6. ^ abcdef Paul, Matías R. (9 de abril de 2002). "[fd-dev] CuteMouse 2.0 alfa 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 acciones extrañas en Unix". Laboratorios Bell . 2002-06-22. 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". La sociedad del patrimonio de Unix . Archivado desde el original el 26 de marzo de 2023.
  10. ^ "El árbol Unix V7/usr/sys/sys/sys1.c". La sociedad del patrimonio de Unix . Archivado desde el original el 26 de marzo de 2023.
  11. ^ "Especificación PNG (Portable Network Graphics) Versión 1.0: 12.11. Firma de archivo PNG". MIT . 1996-10-01. Archivado desde el original el 26 de marzo de 2023.
  12. ^ Chen, Raymond (24 de marzo de 2008). "¿Cuál es la diferencia entre las extensiones COM y EXE?". Lo viejo y nuevo . Archivado desde el original el 18 de febrero de 2019.
  13. ^ abc Paul, Matthias R. (3 de abril de 2002). "[fd-dev] Ctrl+Alt+Supr". 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 PC de IBM (0000h, 1234h), administradores de memoria de DOS como EMM386 (1234h) y cachés de disco como SMARTDRV (EBABh, BABEh) y NWCACHE (0EDCh, EBABh, 6756h). )
  14. ^ "El proceso de arranque BIOS/MBR". Base de conocimientos de NeoSmart . 2015-01-25. Archivado desde el original el 26 de marzo de 2023 . Consultado el 3 de febrero de 2019 .
  15. ^ "Comunidad TI E2E: ¿Alguien sabe si las siguientes configuraciones se pueden realizar con la herramienta MCP CLI?". Instrumentos Texas . 2011-08-27. Archivado desde el original el 7 de octubre de 2022.
  16. ^ Poley, Josh (30 de septiembre de 2009). "Números mágicos: números enteros". Aprender . Microsoft . Archivado desde el original el 28 de marzo de 2023.
  17. ^ Recién llegado, Joseph M. (13 de octubre de 2001). "Gestión de mensajes: garantizar la unicidad". Fusión de desarrolladores . 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 sólo son únicos si los genera..." WebLog de Larry Osterman - Confesiones de un viejo Fogy . MSDN. Archivado desde el original el 28 de marzo de 2023 . Consultado el 16 de noviembre de 2007 .
  19. ^ "Implementación de subprogramas de Java con versiones familiares JRE en el complemento Java para Internet Explorer". Oráculo . Archivado desde el original el 30 de noviembre de 2022 . Consultado el 28 de marzo de 2023 .
  20. ^ "Instalación de GNU GRUB, Sección 3.4: Instalación del BIOS". Gnu.org . Archivado desde el original el 15 de marzo de 2023 . Consultado el 26 de junio de 2014 .
  21. ^ Heddings, Lowell (3 de noviembre de 2014). "Números mágicos: los códigos secretos que los programadores ocultan en su PC". Cómo hacerlo geek . Archivado desde el original el 26 de marzo de 2023 . Consultado el 3 de octubre de 2017 .
  22. ^ Cavit, Doug (24 de abril de 2012). "Protegerse contra la reutilización de referencias a objetos obsoletos". Microsoft seguro . Archivado desde el original el 26 de julio de 2018 . Consultado el 26 de julio de 2018 .
  23. ^ Bolena, Erich Stefan (4 de abril de 1995). "Comentarios sobre la propuesta 'MultiBoot Standard'". Uruk.org . Archivado desde el original el 26 de marzo de 2023.
  24. ^ abcdef "Nota técnica TN2151: comprensión y análisis de informes de fallos de aplicaciones". Documentación para desarrolladores de Apple . 2009-01-29. Archivado desde el original el 13 de diciembre de 2018.
  25. ^ abcdef Birkett, Andrés. "Partes internas del montón CRT de depuración de Win32". Nobugs.org .
  26. ^ McNamara, Paul (19 de julio de 2012). "El código de Microsoft contiene la frase 'pechos grandes'... Sí, de verdad". Mundo de la Red .
  27. ^ WebKit, el proyecto de código abierto WebKit, 2023-01-06 , consultado el 6 de enero de 2023
  28. ^ "AddressSanitizer - Preguntas frecuentes". GitHub . Consultado el 18 de mayo de 2022 .
  29. ^ "MANUAL DE REFERENCIA DEL PROGRAMADOR INTEL 80386". MIT .
  30. ^ Scheppner, Carolyn. "Guía de Amiga Mail Vol.2". Cataclismo.cx . Archivado desde el original el 18 de julio de 2011 . Consultado el 20 de agosto de 2010 .
  31. ^ "Comprobación de errores 0xDEADDEAD MANUALLY_INITIATED_CRASH1". Documentación de Microsoft . 2023-06-19.
  32. ^ "Safari versión 14.0.1 se cierra inesperadamente".
  33. ^ "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 .