Ohjelmointi- ja kääntäjäteoriassa tavoittamaton koodi on osa ohjelmakoodia, jota ei voida missään olosuhteissa suorittaa, koska se ei ole tavoitettavissa ohjausvuokaaviossa [ 1] [2] .
Tavoittelematonta koodia kutsutaan usein yhdeksi kuolleen koodin tyypeistä , tätä terminologiaa käytetään yleensä harkittaessa ohjelmien lähdekoodia [ 3] [4] . Kääntäjäteoriassa nämä käsitteet eivät kuitenkaan liity millään tavalla, kuollut koodi on vain saavutettavissa oleva koodi, joka ei vaikuta ohjelman ulostuloon [ 1] [2] [5] .
Tärkeimmät haitat siitä, että ohjelmassa on tavoittamaton koodi, ovat:
Tavoittelemattoman koodin olemassaolo voi johtua useista tekijöistä, kuten:
Viidessä viimeisessä tapauksessa tavoittamaton koodi on vanhaa koodia, toisin sanoen koodia, joka oli kerran hyödyllinen, mutta jota ei enää käytetä.
Harkitse seuraavaa C -esimerkkiä :
int foo ( int x , int y ) { paluu x + y _ int z = x * y ; /* Koodi, jota ei tavoiteta */ }Toiminto int z = x*yon tavoittamaton koodi, koska proseduuri poistuu ennen sitä (proseduurista palaamisen jälkeiset toiminnot eivät välttämättä ole tavoittamaton koodi, esim. jos returnin jälkeiseen etikettiin viitataan goto -käskyllä ).
Saavutettavan koodin löytäminen lähdekoodista voidaan tehdä staattisen koodianalyysin avulla [3] [4] . Optimoivassa kääntäjässä tavoittamattoman koodin poiston optimointi pystyy havaitsemaan ja poistamaan tavoittamattoman koodin , joka löytää tavoittamattomat solmut ohjausvuokaaviosta (CFG) ja poistaa ne [6] . Yksinkertainen CFG-graafin analyysi tavoittamattomiin solmuihin on usein toteutettu kääntäjässä erillisenä funktiona, ns. roskakeräin , jota kutsutaan välittömästi muunnosten jälkeen, jotka voivat muuttaa ohjausvirtauskaaviota [7] .
-väliesitykseen suoritettujen kääntäjien muunnosten , kuten yleisten alilausekkeiden poistooptimointien seurauksena .
Käytännössä toteutettavan analyysin monimutkaisuus vaikuttaa merkittävästi havaittavan tavoittamattoman koodin määrään. Esimerkiksi jatkuvan taittamisen ja yksinkertaisen ohjausvirta - analyysin jälkeen saatat huomata, että ifseuraavan esimerkin käskyn sisällä oleva koodi ei ole tavoitettavissa:
int foo ( tyhjä ) { int n = 2 + 1 ; jos ( n > 4 ) { printf ( "%d" , n ); /* Koodi, jota ei tavoiteta */ } }Kuitenkin, jotta tunnistettaisiin koodi, jota ei voida saavuttaa seuraavassa esimerkissä, on käytettävä paljon kehittyneempää analyysialgoritmia:
int foo ( tyhjä ) { tupla x = sqrt ( 2 ); jos ( x > 4 ) { printf ( "%lf" , x ); /* Koodi, jota ei tavoiteta */ } }Yksi käytännöllinen ratkaisu on tehdä ensin yksinkertainen saavuttamaton koodianalyysi ja sitten käsitellä monimutkaisempia tapauksia profiloijalla . Profiloija ei voi todistaa, että koodinpätkä ei ole tavoitettavissa, mutta se voi olla hyvä heuristinen keino löytää epäilyttäviä solmuja, joihin ei todennäköisesti saada yhteyttä. Kun nämä mahdollisesti tavoittamattomat solmut on löydetty, voidaan käyttää jotakin tehokasta tavoittamattoman koodin analyysialgoritmia.