stringtranslate.com

Магическое число (программирование)

В компьютерном программировании магическим числом является любое из следующих:

Неназванные числовые константы

Термин магическое число или магическая константа относится к анти-шаблону использования чисел непосредственно в исходном коде. Это было названо нарушением одного из старейших правил программирования, восходящего к руководствам COBOL , FORTRAN и PL/1 1960-х годов. [1] Использование неназванных магических чисел в коде скрывает намерение разработчиков при выборе этого числа, [2] увеличивает вероятность тонких ошибок (например, каждая ли цифра в числе 3,14159265358979323846 верна и может ли оно быть округлено до 3,14159? [3] ) и затрудняет адаптацию и расширение программы в будущем. [4] Замена всех значимых магических чисел именованными константами (также называемыми пояснительными переменными) делает программы более простыми для чтения, понимания и поддержки. [5]

Имена, выбранные так, чтобы они были значимыми в контексте программы, могут привести к тому, что код будет легче понять сопровождающему, который не является первоначальным автором (или даже первоначальным автором по прошествии некоторого времени). [6] Примером неинформативно названной константы является int SIXTEEN = 16, тогда как int NUMBER_OF_BITS = 16является более описательным.

Проблемы, связанные с магическими «числами», описанные выше, не ограничиваются числовыми типами, и этот термин также применяется к другим типам данных, где объявление именованной константы было бы более гибким и коммуникативным. [1] Таким образом, объявление const string testUserName = "John"лучше, чем несколько вхождений «магического значения» "John"в тестовом наборе .

Например, если требуется случайным образом перетасовать значения в массиве, представляющем стандартную колоду игральных карт , этот псевдокод выполнит эту работу, используя алгоритм тасования Фишера–Йетса :

для i от 1 до 52 j := i + randomInt(53 - i) - 1 а.swapEntries(i, j)

где a— объект массива, функция randomInt(x)выбирает случайное целое число от 1 до x включительно и swapEntries(i, j)меняет местами i -ю и j -ю записи в массиве. В предыдущем примере 52— магическое число. Считается лучшим стилем программирования написать следующее:

int deckSize:= 52 для i от 1 до deckSize j := i + randomInt(deckSize + 1 - i) - 1 а.swapEntries(i, j)

Это предпочтительнее по нескольким причинам:

функция shuffle ( int deckSize) для i от 1 до deckSize j := i + randomInt(deckSize + 1 - i) - 1 а.swapEntries(i, j)

Недостатки:

Принятые виды использования

В некоторых контекстах использование неназванных числовых констант является общепринятым (и, возможно, «не магическим»). Хотя такое принятие субъективно и часто зависит от индивидуальных привычек кодирования, ниже приведены распространенные примеры:

Константы 1 и 0 иногда используются для представления булевых значений true и false в языках программирования без булевого типа, таких как старые версии C. Большинство современных языков программирования предоставляют примитивный типboolean или , поэтому использование 0 и 1 нецелесообразно. Это может быть еще более запутанным, поскольку 0 иногда означает программный успех (когда -1 означает неудачу) и неудачу в других случаях (когда 1 означает успех).bool

В C и C++ 0 представляет нулевой указатель . Как и в случае с булевыми значениями, стандартная библиотека C включает определение макроса NULL, использование которого поощряется. Другие языки предоставляют определенное значение nullor nil, и в этом случае не следует использовать альтернативу. Типизированная константа указателя nullptrбыла введена в C++11.

Индикаторы формата

Источник

Индикаторы формата впервые были использованы в исходном коде ранней версии 7 Unix . [ необходима ссылка ]

Unix был перенесен на один из первых DEC PDP-11 /20, который не имел защиты памяти . Поэтому ранние версии Unix использовали модель перемещаемой ссылки памяти . [7] Версии Unix до шестого издания считывали исполняемый файл в память и переходили на первый нижний адрес памяти программы, относительный адрес ноль. С развитием страничных версий Unix был создан заголовок для описания исполняемых компонентов образа . Кроме того, инструкция ветвления была вставлена ​​как первое слово заголовка, чтобы пропустить заголовок и запустить программу. Таким образом, программа могла быть запущена в старом режиме перемещаемой ссылки памяти (обычном) или в страничном режиме. По мере разработки большего количества исполняемых форматов добавлялись новые константы путем увеличения смещения ветвления . [8]

В исходном коде шестого издания загрузчика программ Unix функция exec() считывала исполняемый ( двоичный ) образ из файловой системы. Первые 8 байт файла были заголовком , содержащим размеры программной (текстовой) и инициализированных (глобальных) областей данных. Кроме того, первое 16-битное слово заголовка сравнивалось с двумя константами , чтобы определить, содержит ли исполняемый образ перемещаемые ссылки на память (обычные), недавно реализованный исполняемый образ с подкачкой только для чтения или разделенный образ инструкции и подкачкой данных. [9] Не было никакого упоминания о двойной роли константы заголовка, но старший байт константы был, по сути, кодом операции для инструкции ветвления PDP-11 ( восьмеричное 000407 или шестнадцатеричное 0107). Добавление семи к счетчику программ показало, что если эта константа была выполнена , она перейдет к службе Unix exec() по восьмибайтовому заголовку исполняемого образа и запустит программу.

Поскольку шестое и седьмое издания Unix использовали код подкачки, двойная роль константы заголовка была скрыта. То есть, служба exec() считывала данные заголовка исполняемого файла ( meta ) в буфер пространства ядра , но считывала исполняемый образ в пространство пользователя , тем самым не используя функцию ветвления константы. Создание магических чисел было реализовано в компоновщике и загрузчике Unix , а ветвление магических чисел, вероятно, все еще использовалось в наборе автономных диагностических программ , которые поставлялись с шестым и седьмым изданиями. Таким образом, константа заголовка действительно создавала иллюзию и соответствовала критериям magic .

В седьмой версии Unix константа заголовка не проверялась напрямую, а была назначена переменной с меткой ux_mag [10] и впоследствии упоминалась как магическое число . Вероятно, из-за своей уникальности термин магическое число стал обозначать тип исполняемого формата, затем был расширен до типа файловой системы и снова расширен до любого типа файла.

В файлах

Магические числа распространены в программах во многих операционных системах. Магические числа реализуют строго типизированные данные и являются формой внутриполосной сигнализации для управляющей программы, которая считывает тип(ы) данных во время выполнения программы. Многие файлы имеют такие константы, которые идентифицируют содержащиеся данные. Обнаружение таких констант в файлах является простым и эффективным способом различения многих форматов файлов и может дать дополнительную информацию во время выполнения .

Примеры
Обнаружение

Утилитная программа Unix fileможет считывать и интерпретировать магические числа из файлов, а файл, который используется для анализа информации, называется magic . Утилита Windows TrID имеет схожее назначение.

В протоколах

Примеры

В интерфейсах

Магические числа широко используются в функциях и интерфейсах API многих операционных систем , включая DOS , Windows и NetWare :

Примеры

Другие применения

Примеры

Ограничения по типу данных

Это список ограничений типов хранения данных: [16]

GUID-ы

Можно создавать или изменять глобально уникальные идентификаторы (GUID) так, чтобы они были запоминающимися, но это крайне не рекомендуется, поскольку это ставит под угрозу их силу как почти уникальных идентификаторов. [17] [18] Спецификации для генерации GUID и UUID довольно сложны, что приводит к тому, что они фактически уникальны, если реализованы правильно. [19]

Номера идентификаторов продуктов Microsoft Windows для продуктов Microsoft Office иногда заканчиваются на 0000-0000-0000000FF1CE(«OFFICE»), например { 90160000-008C-0000-0000-0000000FF1CE}, идентификатор продукта для «Компонента расширяемости Office 16 Click-to-Run».

Java использует несколько GUID, начинающихся с CAFEEFAC. [20]

В таблице разделов GUID схемы разбиения GPT загрузочные разделы BIOS используют специальный GUID { 21686148-6449-6E6F-744E-656564454649} [21] , который не следует определению GUID; вместо этого он формируется с использованием кодов ASCII для строки " Hah!IdontNeedEFI" частично в прямом порядке байтов . [22]

Отладочные значения

Значения магической отладки — это определенные значения, записываемые в память во время выделения или освобождения, чтобы впоследствии можно было определить, были ли они повреждены, и сделать очевидным, когда используются значения, взятые из неинициализированной памяти. Память обычно отображается в шестнадцатеричном формате, поэтому часто встречаются запоминающиеся повторяющиеся или шестнадцатеричные значения. Численно нечетные значения могут быть предпочтительными, чтобы процессоры без байтовой адресации выдавали ошибку при попытке использовать их в качестве указателей (которые должны попадать на четные адреса). Значения следует выбирать так, чтобы они находились вдали от вероятных адресов (код программы, статические данные, данные кучи или стек). Аналогично их можно выбирать так, чтобы они не были допустимыми кодами в наборе инструкций для данной архитектуры.

Поскольку маловероятно, хотя и возможно, что 32-разрядное целое число примет это конкретное значение, появление такого числа в отладчике или дампе памяти, скорее всего, указывает на ошибку, например, переполнение буфера или неинициализированную переменную .

Известные и распространённые примеры включают в себя:

Большинство из них имеют длину 32 бита — размер слова большинства компьютеров с 32-битной архитектурой.

Распространенность этих ценностей в технологиях Microsoft не является совпадением; они подробно обсуждаются в книге Стива Магуайра Writing Solid Code из Microsoft Press . Он приводит ряд критериев для этих ценностей, таких как:

Поскольку они часто использовались для обозначения областей памяти, которые были по сути пустыми, некоторые из этих терминов стали использоваться во фразах, означающих «исчез, прерван, стерт из памяти»; например, «Ваша программа DEADBEEF». [ необходима цитата ]

Смотрите также

Ссылки

  1. ^ abc Martin, Robert C. (2009). "Глава 17: Запахи и эвристики - G25 Замена магических чисел именованными константами". Чистый код - Справочник по гибкому программному мастерству . Бостон: Prentice Hall. стр. 300. ISBN 978-0-13-235088-4.
  2. ^ Мартин, Роберт С. (2009). "Глава 17: Запахи и эвристики - G16 Obscured Intent". Чистый код - Справочник по гибкому программному мастерству . Бостон: Prentice Hall. стр. 295. ISBN 978-0-13-235088-4.
  3. ^ Контьери, Макси (2020-10-20). "Code Smell 02 - Константы и магические числа". Максимилиано Контьери - Разработка программного обеспечения . Получено 2024-03-21 .
  4. ^ Магуайр, Джеймс (2008-12-09). "Бьярн Страуструп об обучении разработчиков программного обеспечения". Datamation.com . Архивировано из оригинала 2018-06-23.
  5. ^ Фогель, Джефф (29.05.2007). «Шесть способов писать более понятный код». IBM Developer . Архивировано из оригинала 26.09.2018.
  6. ^ abcdef Пол, Маттиас Р. (2002-04-09). "[fd-dev] CuteMouse 2.0 alpha 1". freedos-dev . Архивировано из оригинала 2022-04-07 . Получено 2022-08-04 .
  7. ^ "Странные комментарии и странные дела в Unix". Bell Labs . 2002-06-22. Архивировано из оригинала 2006-11-04.
  8. Личное общение с Деннисом М. Ричи.
  9. ^ "The Unix Tree V6/usr/sys/ken/sys1.c". The Unix Heritage Society . Архивировано из оригинала 2023-03-26.
  10. ^ "The Unix Tree V7/usr/sys/sys/sys1.c". The Unix Heritage Society . Архивировано из оригинала 2023-03-26.
  11. ^ "Спецификация PNG (переносимая сетевая графика) версии 1.0: 12.11. Подпись файла PNG". MIT . 1996-10-01. Архивировано из оригинала 2023-03-26.
  12. ^ Чен, Рэймонд (2008-03-24). "В чем разница между расширениями COM и EXE?". The Old New Thing . Архивировано из оригинала 2019-02-18.
  13. ^ abc Пол, Маттиас Р. (2002-04-03). "[fd-dev] Ctrl+Alt+Del". freedos-dev . Архивировано из оригинала 2017-09-09 . Получено 2017-09-09 .(Примечание. Упоминается ряд магических значений, используемых IBM PC -совместимыми BIOS (0000h, 1234h), менеджерами памяти DOS , такими как EMM386 (1234h), и дисковыми кэшами, такими как SMARTDRV (EBABh, BABEh) и NWCACHE (0EDCh, EBABh, 6756h).)
  14. ^ "Процесс загрузки BIOS/MBR". База знаний NeoSmart . 2015-01-25. Архивировано из оригинала 2023-03-26 . Получено 2019-02-03 .
  15. ^ «Сообщество TI E2E: кто-нибудь знает, можно ли выполнить следующие конфигурации с помощью инструмента MCP CLI?». Texas Instruments . 2011-08-27. Архивировано из оригинала 2022-10-07.
  16. ^ Поли, Джош (2009-09-30). "Волшебные числа: целые числа". Learn . Microsoft . Архивировано из оригинала 2023-03-28.
  17. ^ Newcomer, Joseph M. (2001-10-13). "Message Management: Guaranteeing uniqueness". Developer Fusion . Архивировано из оригинала 2005-04-21 . Получено 2007-11-16 .
  18. ^ Остерман, Ларри (21.07.2005). «UUID уникальны только в том случае, если вы их генерируете...» Веб-журнал Ларри Остермана — Признания старого чудака . MSDN. Архивировано из оригинала 28.03.2023 . Получено 16.11.2007 .
  19. ^ "RFC 9562 - Универсально уникальные идентификаторы (UUID)". ietf.org . Май 2024 . Получено 2024-08-09 .
  20. ^ "Развертывание Java-апплетов с версиями JRE семейства в подключаемом модуле Java для Internet Explorer". Oracle . Архивировано из оригинала 2022-11-30 . Получено 2023-03-28 .
  21. ^ "Установка GNU GRUB, раздел 3.4: Установка BIOS". Gnu.org . Архивировано из оригинала 2023-03-15 . Получено 2014-06-26 .
  22. ^ Хеддингс, Лоуэлл (2014-11-03). "Магические числа: секретные коды, которые программисты скрывают на вашем ПК". How-To Geek . Архивировано из оригинала 2023-03-26 . Получено 2017-10-03 .
  23. ^ Cavit, Doug (2012-04-24). «Защита от повторного использования устаревших ссылок на объекты». Microsoft Secure . Архивировано из оригинала 2018-07-26 . Получено 2018-07-26 .
  24. ^ Болейн, Эрих Стефан (1995-04-04). "Комментарии к предложению 'MultiBoot Standard'". Uruk.org . Архивировано из оригинала 2023-03-26.
  25. ^ abcdef "Техническое примечание TN2151: Понимание и анализ отчетов о сбоях приложений". Документация разработчиков Apple . 2009-01-29. Архивировано из оригинала 2018-12-13.
  26. ^ abcdef Биркетт, Эндрю. "Внутреннее устройство кучи Win32 Debug CRT". Nobugs.org .
  27. ^ Макнамара, Пол (2012-07-19). «Код Microsoft содержит фразу „большие сиськи“... Да, действительно». Network World .
  28. ^ WebKit, проект с открытым исходным кодом WebKit, 2023-01-06 , получено 2023-01-06
  29. ^ "AddressSanitizer - FAQ". GitHub . Получено 2022-05-18 .
  30. ^ "СПРАВОЧНОЕ РУКОВОДСТВО ПРОГРАММИСТА INTEL 80386". MIT .
  31. ^ Шеппнер, Кэролин. "Amiga Mail Vol.2 Guide". Cataclysm.cx . Архивировано из оригинала 2011-07-18 . Получено 2010-08-20 .
  32. ^ "Проверка ошибки 0xDEADDEAD MANUALLY_INITIATED_CRASH1". Документация Microsoft . 2023-06-19.
  33. ^ «Safari версии 14.0.1 неожиданно завершает работу».
  34. ^ «Спецификация дерева устройств».
  35. ^ "strncat_s, _strncat_s_l, wcsncat_s, _wcsncat_s_l, _mbsncat_s, _mbsncat_s_l". Документация Microsoft . Получено 2019-01-16 .