stringtranslate.com

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

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

Безымянные числовые константы

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

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

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

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

для меня от 1 до 52 j := я + randomInt(53 - i) - 1 а.swapEntries(я, 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(я, j)

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

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

Недостатками являются:

Допустимое использование

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

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

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

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

Источник

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

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

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

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

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

В файлах

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

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

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

В протоколах

Примеры

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

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

Примеры

Другое использование

Примеры

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

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

GUID

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

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

Java использует несколько идентификаторов GUID, начиная с CAFEEFAC. [18]

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

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

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

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

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

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

Преобладание этих ценностей в технологиях Microsoft не случайно; они подробно обсуждаются в книге Стива Магуайра «Написание надежного кода» , изданной Microsoft Press . Он дает различные критерии этих ценностей, такие как:

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

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

Рекомендации

  1. ^ abc Мартин, Роберт С. (2009). «Глава 17: Запахи и эвристика - G25 Замените магические числа именованными константами». Чистый код — Руководство по созданию гибкого программного обеспечения . Бостон: Прентис Холл. п. 300. ИСБН 978-0-13-235088-4.
  2. ^ Мартин, Роберт С. (2009). «Глава 17: Запахи и эвристика - Скрытое намерение G16». Чистый код — Руководство по созданию гибкого программного обеспечения . Бостон: Прентис Холл. п. 295. ИСБН 978-0-13-235088-4.
  3. ^ Магуайр, Джеймс (9 декабря 2008 г.). «Бьерн Страуструп об обучении разработчиков программного обеспечения». Datamation.com . Архивировано из оригинала 23 июня 2018 г.
  4. ^ Фогель, Джефф (29 мая 2007 г.). «Шесть способов написать более понятный код». Разработчик IBM . Архивировано из оригинала 26 сентября 2018 г.
  5. ^ abcdef Пол, Матиас Р. (9 апреля 2002 г.). «[fd-dev] CuteMouse 2.0 альфа 1». freedos-dev . Архивировано из оригинала 7 апреля 2022 г. Проверено 4 августа 2022 г.
  6. ^ «Странные комментарии и странные действия в Unix». Лаборатории Белла . 22 июня 2002 г. Архивировано из оригинала 4 ноября 2006 г.
  7. ^ Личное общение с Деннисом М. Ричи.
  8. ^ "Дерево Unix V6/usr/sys/ken/sys1.c" . Общество наследия Unix . Архивировано из оригинала 26 марта 2023 г.
  9. ^ "Дерево Unix V7/usr/sys/sys/sys1.c" . Общество наследия Unix . Архивировано из оригинала 26 марта 2023 г.
  10. ^ «Спецификация PNG (портативная сетевая графика), версия 1.0: 12.11. Подпись файла PNG» . Массачусетский технологический институт . 01.10.1996. Архивировано из оригинала 26 марта 2023 г.
  11. ^ Чен, Раймонд (24 марта 2008 г.). «В чем разница между расширениями COM и EXE?». Старая новая вещь . Архивировано из оригинала 18 февраля 2019 г.
  12. ^ abc Пол, Матиас Р. (3 апреля 2002 г.). «[fd-dev] Ctrl+Alt+Del». freedos-dev . Архивировано из оригинала 9 сентября 2017 г. Проверено 9 сентября 2017 г.(Примечание. Упоминается ряд магических значений, используемых IBM PC -совместимыми BIOS (0000h, 1234h), менеджерами памяти DOS , такими как EMM386 (1234h), и дисковыми кэшами, такими как SMARTDRV (EBABh, BABEh) и NWCACHE (0EDCh, EBABh, 6756h). )
  13. ^ «Процесс загрузки BIOS/MBR» . База знаний NeoSmart . 25 января 2015 г. Архивировано из оригинала 26 марта 2023 г. Проверено 3 февраля 2019 г.
  14. ^ «Сообщество TI E2E: кто-нибудь знает, можно ли выполнить следующие конфигурации с помощью инструмента MCP CLI?». Инструменты Техаса . 27 августа 2011 г. Архивировано из оригинала 07.10.2022.
  15. ^ Поли, Джош (30 сентября 2009 г.). «Магические числа: целые числа». Учиться . Майкрософт . Архивировано из оригинала 28 марта 2023 г.
  16. ^ Новичок, Джозеф М. (13 октября 2001 г.). «Управление сообщениями: гарантия уникальности». Разработчик Fusion . Архивировано из оригинала 21 апреля 2005 г. Проверено 16 ноября 2007 г.
  17. ^ Остерман, Ларри (21 июля 2005 г.). «UUID уникальны только в том случае, если вы их генерируете…» Веб-журнал Ларри Остермана — «Исповедь старой туманности» . MSDN. Архивировано из оригинала 28 марта 2023 г. Проверено 16 ноября 2007 г.
  18. ^ «Развертывание Java-апплетов с семейными версиями JRE в подключаемом модуле Java для Internet Explorer» . Оракул . Архивировано из оригинала 30 ноября 2022 г. Проверено 28 марта 2023 г.
  19. ^ «Установка GNU GRUB, Раздел 3.4: Установка BIOS» . Gnu.org . Архивировано из оригинала 15 марта 2023 г. Проверено 26 июня 2014 г.
  20. ^ Хеддингс, Лоуэлл (3 ноября 2014 г.). «Волшебные числа: секретные коды, которые программисты скрывают на вашем компьютере». Как компьютерщик . Архивировано из оригинала 26 марта 2023 г. Проверено 3 октября 2017 г.
  21. ^ Кавит, Дуг (24 апреля 2012 г.). «Защита от повторного использования устаревших ссылок на объекты». Microsoft Secure . Архивировано из оригинала 26 июля 2018 г. Проверено 26 июля 2018 г.
  22. ^ Болейн, Эрих Стефан (4 апреля 1995 г.). «Комментарии к предложению «MultiBoot Standard»». Урук.орг . Архивировано из оригинала 26 марта 2023 г.
  23. ^ abcdef «Техническое примечание TN2151: Понимание и анализ отчетов о сбоях приложений». Документация разработчика Apple . 29 января 2009 г. Архивировано из оригинала 13 декабря 2018 г.
  24. ^ abcdef Биркетт, Эндрю. «Внутреннее устройство кучи CRT отладки Win32». Nobugs.org .
  25. ^ Макнамара, Пол (19 июля 2012 г.). «Код Microsoft содержит фразу «большие сиськи»… Да, правда». Сетевой мир .
  26. ^ WebKit, Проект с открытым исходным кодом WebKit, 06 января 2023 г. , получено 6 января 2023 г.
  27. ^ «AddressSanitizer — Часто задаваемые вопросы» . Гитхаб . Проверено 18 мая 2022 г.
  28. ^ "" INTEL 80386 Справочное руководство для программиста"". Массачусетский технологический институт .
  29. ^ Шеппнер, Кэролайн. «Руководство по Amiga Mail Vol.2». Катаклизм.cx . Архивировано из оригинала 18 июля 2011 г. Проверено 20 августа 2010 г.
  30. ^ «Проверка ошибок 0xDEADDEAD MANUALLY_INITIATED_CRASH1» . Документация Майкрософт . 19 июня 2023 г.
  31. ^ «Версия Safari 14.0.1 неожиданно закрывается» .
  32. ^ "strncat_s, _strncat_s_l, wcsncat_s, _wcsncat_s_l, _mbsncat_s, _mbsncat_s_l". Документация Майкрософт . Проверено 16 января 2019 г.