Недостижимый код

редактировать

В компьютерном программировании, недостижимый код является частью источника код программы, который никогда не может быть выполнен из-за отсутствия потока управления пути к коду из остальной части программы.

Недостижимый код иногда также называют мертвым кодом, хотя мертвый код может также относиться к коду, который выполняется, но не влияет на вывод программы.

Недоступный код обычно считается нежелательным по нескольким причинам:

  • Он использует память излишне
  • Это может вызвать ненужное использование кэша инструкций ЦП
  • Время и усилия могут быть потрачены на тестирование, поддержку и документирование кода, который никогда не использовано
    • Иногда автоматический тест - единственное, что использует код.

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

Содержание
  • 1 Причины
  • 2 Примеры
    • 2.1 ошибка goto fail
    • 2.2 C ++
  • 3 Анализ
    • 3.1 Недоступность и профилирование
  • 4 См. Также
  • 5 Ссылки
Причины

Недостижимый код может существовать по многим причинам, например:

  • ошибки программирования в сложных условных ветвях
  • следствие внутренних преобразований, выполненных оптимизирующим компилятором ;
  • Неполное тестирование нового или измененного кода
  • Устаревший код
    • Код, замененный другой реализацией
    • Недоступный код, который программист решил не удалять, потому что он смешан с достижимым code
    • Потенциально доступный код, который в текущих сценариях использования не требуется
    • Неактивный код, который намеренно сохраняется на случай, если он понадобится позже
  • Код, используемый только для отладки.

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

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

Примеры

В этом фрагменте кода C:

int foo (int X, int Y) {return X + Y; int Z = X * Y; }

определение int Z = X * Y;никогда не достигается, поскольку функция всегда возвращает до него. Следовательно, Zне нужно ни выделять память, ни инициализировать.

ошибка goto fail

Apple SSL / TLS от февраля 2014 года содержала серьезную уязвимость безопасности, официально известную как CVE - 2014-1266 и неофициально как «ошибка перехода». Соответствующий фрагмент кода:

static OSStatus SSLVerifySignedServerKeyExchange (SSLContext * ctx, bool isRsa, SSLBuffer signedParams, uint8_t * signature, UInt16 signatureLen) {OSStatus err;... if ((err = SSLHashSHA1.update (hashCtx, serverRandom))! = 0) перейти к ошибке; if ((err = SSLHashSHA1.update (hashCtx, signedParams))! = 0) перейти к ошибке; перейти к неудаче; if ((err = SSLHashSHA1.final (hashCtx, hashOut))! = 0) goto fail;... сбой: SSLFreeBuffer (signedHashes); SSLFreeBuffer (hashCtx); return err; }

Здесь два последовательных вызова goto fail. В синтаксисе языка C второе является безусловным и, следовательно, всегда пропускает вызов SSLHashSHA1.final. Как следствие, errбудет содержать статус операции обновления SHA1, и проверка подписи никогда не завершится ошибкой.

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

C ++

In C ++, для некоторых конструкций указано поведение undefined. Компилятор может реализовать любое поведение или ничего, и обычно оптимизирующий компилятор предполагает, что код недоступен.

Анализ

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

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

На практике сложность анализа оказывает значительное влияние на количество обнаруживаемого недостижимого кода. Например, сворачивание констант и простой анализ потока показывают, что внутренняя часть оператора if в следующем коде недоступна:

int N = 2 + 1; if (N == 4) {/ * unreachable * /}

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

double X = sqrt (2) ; if (X>5) {/ * unreachable * /}

Техника устранения недостижимого кода относится к тому же классу оптимизаций, что и устранение мертвого кода и удаление избыточного кода.

Недоступность и профилирование

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

См. Также
Ссылки
  • Appel, A. W. 1998 Современная реализация компилятора на Java. Издательство Кембриджского университета.
  • Мучник С.С. 1997 Продвинутая разработка и реализация компилятора. Морган Кауфманн.
Последняя правка сделана 2021-06-20 02:26:27
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте