V teorii programování a kompilátoru je nedosažitelný kód částí programového kódu, kterou za žádných okolností nelze spustit, protože je nedosažitelný v grafu toku řízení [1] [2] .
Nedosažitelný kód je často označován jako jeden z typů mrtvého kódu , tato terminologie se obvykle používá při zvažování zdrojového kódu programů [3] [4] . V teorii překladačů však tyto pojmy nejsou nijak propojeny, mrtvý kód je pouze dosažitelný kód, který neovlivňuje výstup programu [1] [2] [5] .
Hlavní nevýhody nedostupného kódu v programu jsou:
Existence nedostupného kódu může být způsobena různými faktory, například:
V posledních pěti případech je nedosažitelný kód starší kód, tedy kód, který byl kdysi užitečný, ale již se nepoužívá.
Zvažte následující příklad C :
int foo ( int x , int y ) { vrátit x + y _ int z = x * y ; /* Nedosažitelný kód */ }Operace int z = x*yje nedosažitelný kód, protože procedura končí před ní (operace po návratu z procedury nemusí být nedosažitelný kód, například pokud na návěští po návratu odkazuje příkaz goto ).
Nalezení nedosažitelného kódu ve zdrojovém kódu lze provést pomocí statické analýzy kódu [3] [4] . V optimalizujícím kompilátoru je optimalizace odstranění nedosažitelného kódu schopna detekovat a odstranit nedostupný kód , který najde nedosažitelné uzly v grafu řídicího toku (CFG) a odstraní je [6] . Jednoduchý rozbor CFG grafu do nedosažitelných uzlů je v překladači často implementován jako samostatná funkce, tzv. garbage collector , který je volán ihned po transformacích, které mohou změnit graf toku řízení [7] .
Kód se může stát nedosažitelným v důsledku jiných transformací kompilátoru prováděných na mezilehlé reprezentaci , jako jsou například optimalizace odstraňování běžných podvýrazů .
V praxi složitost implementované analýzy významně ovlivňuje množství detekovaného nedostupného kódu. Například po neustálém skládání a jednoduché analýze toku řízení můžete zjistit, že kód uvnitř příkazu ifv následujícím příkladu je nedostupný:
int foo ( void ) { int n = 2 + 1 ; jestliže ( n > 4 ) { printf ( "%d" , n ); /* Nedosažitelný kód */ } }Aby však bylo možné identifikovat nedosažitelný kód v následujícím příkladu, je třeba použít mnohem sofistikovanější analytický algoritmus:
int foo ( void ) { double x = sqrt ( 2 ); pokud ( x > 4 ) { printf ( "%lf" , x ); /* Nedosažitelný kód */ } }Jedním z praktických řešení je nejprve provést jednoduchou analýzu nedosažitelného kódu a poté použít profiler ke zpracování složitějších případů. Profiler nemůže prokázat, že část kódu je nedosažitelná, ale může to být dobrá heuristika pro nalezení podezřelých uzlů, které jsou pravděpodobně nedosažitelné. Jakmile jsou tyto potenciálně nedosažitelné uzly nalezeny, lze použít nějaký výkonný algoritmus analýzy nedosažitelného kódu.