В программировании и теории компиляторов, недостижимым кодом называют часть кода программы, которая ни при каких условиях не может быть исполнена, поскольку является недостижимой в графе потока управления[1][2].
Недостижимый код часто относят к одному из типов мёртвого кода, такая терминология обычно применяется при рассмотрении исходного кода программ[3][4]. Однако в теории компиляторов, эти понятия никак не связаны, мёртвым кодом там называют только достижимый, но не влияющий на вывод программы код[1][2][5].
Основные недостатки наличия в программе недостижимого кода:
Существование недостижимого кода может быть обусловлено разными факторами, например:
В последних пяти случаях, недостижимый код является унаследованным, то есть код, который был однажды полезным, но сейчас не используется.
Рассмотрим следующий пример на языке Си:
int foo(int x, int y)
{
return x + y;
int z = x*y; /* Недостижимый код */
}
Операция int z = x*y
является недостижимым кодом, так как перед ней выполняется выход из процедуры (операции, стоящие после возврата из процедуры могут и не являться недостижимым кодом, например, если на метку, стоящую после возврата ссылается оператор goto).
Поиск недостижимого кода в исходном коде может быть выполнен с помощью статического анализа кода[3][4]. В оптимизирующем компиляторе, выявить и удалить недостижимый код способна оптимизация удаления недостижимого кода, которая находит в графе потока управления недостижимые узлы и удаляет их[6]. Простой анализ CFG-графа на недостижимые узлы часто бывает реализован в компиляторе в виде отдельной функции, т. н. сборщика мусора, которая вызывается сразу после преобразований, способных изменять граф потока управления[7].
Код может становиться недостижимым в результате выполнения других преобразований компилятора над промежуточным представлением[en], например оптимизации удаления общих подвыражений.
На практике, сложность реализуемого анализа существенно влияет на количество выявляемого недостижимого кода. Например, после свёртки констант и простого анализа потока управления можно обнаружить, что код внутри оператора if
в следующем примере является недостижимым:
int foo(void)
{
int n = 2 + 1;
if (n > 4)
{
printf("%d", n); /* Недостижимый код */
}
}
Однако, для того чтобы выявить недостижимый код в следующем примере, необходимо применить гораздо более сложный алгоритм анализа:
int foo(void)
{
double x = sqrt(2);
if (x > 4)
{
printf("%lf", x); /* Недостижимый код */
}
}
Одним из практических решений является подход, выполняющий сначала простой анализ выявления недостижимого кода, а затем использует профилировщик для обработки более сложных случаев. Профилировщик не может доказать, что какой-либо участок кода является недостижимым, но он может быть хорошей эвристикой для нахождения подозрительных узлов, которые, вероятно, являются недостижимыми. После обнаружения этих потенциально недостижимых узлов, можно применить какой нибудь мощный алгоритм анализа недостижимого кода.
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .