Typová kontrola

Typová kontrola je v informatice proces ověřování datových typů ve zdrojovém kódu počítačového programu (pro operandy ve výrazech, parametry a návratové hodnoty funkcí i jinde). Může být prováděna buď překladačem při překladu programu (statická typová kontrola) nebo až běhovým prostředím za běhu programu (dynamická typová kontrola). Programovací jazyky, které vyžadují přísné uvádění datových typů, označujeme za silně typované, ostatní za slabě typované.

Statická typová kontrola

Statická typová kontrola, jako jedna ze sémantických kontrol, ověřuje typy výrazů, zda odpovídají svým kontextům např. požadavek na typ operandu určitého operátoru apod. Odhaluje pouze chyby vyhodnotitelné při překladu, ale kontrolované podmínky jsou společné pro všechna vykonání programu a tak odpadá nutnost opakování typové kontroly při každém spuštění programu. Vynechání typové kontroly za běhu umožňuje efektivnější vykonání programu (rychlé či s menším nárokem na paměť) a další optimalizace. Při pohledu na všechny jazykové konstrukce jako na funkce, jak to dělají funkcionální jazyky, se projeví podobnost s deklaračním problémem u identifikátorů a funkcí, kde je však kromě názvu a typu proměnné zároveň požadována ještě posloupnost (může být i prázdná) argumentů.

U programovacích jazyků používajících statické typování probíhá typová kontrola již v době kompilace. Při programování v těchto jazycích je nutno explicitně deklarovat typy, v OOP obvykle typy proměnných. Mezi staticky typované jazyky patří například Ada, C, C++, C#, Java, Haskell. Většinou nejsou formálně typově bezpečné, protože jejich specifikace umožňuje obcházet statické typové ověření a dovolí provést operace nebezpečné za běhu, které způsobí nežádoucí chování kvůli nesprávnému zadání hodnot.

Dynamická typová kontrola

Dynamická typová kontrola probíhá za běhu programu. Jazyky používající dynamické typování nepožadují specifikaci datového typu u proměnných a ty mohou tudíž odkazovat na hodnotu jakéhokoli typu. Mezi dynamicky typované patří JavaScript, Lisp, Lua, PHP, Prolog, Python, Ruby, Smalltalk. Dynamické typování je pružnější, protože programy generují typy a funkcionalitu na základě běhových dat, ale také častější na běhové chyby, kdy hodnota nabude neočekávaného typu a ten se použije pro další zpracování. Běhová chyba se projeví až daleko od místa svého vzniku a je těžko odhalitelná.

U dynamicky typovaného jazyka se při kompilaci provede pouze syntaktická analýza. Běhové kontroly umožní sofistikovanější přístup, protože využívají současně hodnocení všech statických i dynamických informací. Nevýhodou je nutnost provádění kontroly při každém vykonání programu, případně dokonce i při každé práci s daty. V praxi může dynamické testování objevit mnohem širší rozsah chyb než statická typová kontrola, nicméně neumí ošetřit některé chyby detekované při statické kontrole. Když ale pomineme chyby, které se obvykle za typové nepovažují, například dělení nulou, tak dynamická kontrola má víc informací a tak pokud programátor ví jak na to a kompilátor je na to připraven, lze teoreticky objevit všechny statické chyby. Dynamické testování typů probíhá pouze v použitých částech kódu, např. větvích if-ů, kdežto statická v celém programu. Z tohoto důvodu statické typování odmítne víc programů. A pokud chce programátor kód spustit, musí chyby odstranit.

Kombinace statického a dynamického typování

Přítomnost statického typování v programovacím jazyce nemusí nutně znamenat absenci všech mechanismů dynamické typové kontroly. Java a jiné další jazyky používají sice statické typování, ale pro některé operace požadují testování za běhu. .NET Framework 4.0 dokonce podporuje variantu dynamického typování pomocí namespace System.Dynamic, který je stále statický, ale jeho možnosti jsou zkoumány až za běhu. Všechny jazyky používané v rámci platformy .NET (C++, C#, J#, Visual Basic) se tak stávají plně dynamickými. Každý objekt může být implicitně přetypován do typu dynamic. Nad dynamickým typem je možné provádět všechny operace jako volání metod, přístup k prvkům a vlastnostem, použití indexem i použití jako volání delegáta.

Silné a slabé typování

Silně typovaný jazyk předchází provádění operací na argumentech se špatným datovým typem. Typickým příkladem, který ukazuje problém chybějícího silného typování, je jazyk C. Dovoluje přiřadit hodnoty jednoho typu do jiného, což může sice učinit kód rychlejší a kompaktnější nicméně také ztížit ladění.

Slabě typované jazyky implicitně převádí typy při jejich použití. Například v následujícím příkladu není slabě typovanému jazyku jasný výsledek operace:

var x = 5; // x je typu integer
var y = "37"; // y je typu string
x + y; // ?

Oproti tomu jazyk Visual Basic bude produkovat spustitelný kód, kde dojde k převodu řetězce "37" na číslo 37, přičte se 5 a výsledkem výsledkem celé operace bude číslo 42. Jiné jazyky jako je JavaScript vyhodnotí výsledek tak, že číslo 5 se převede na řetězec "5" a dojde ke sloučení "5" a "37" a výsledkem bude řetězec "537". V obou případech je typ stanoven podle pravidel, které berou v úvahu oba operandy, ale o výsledném datovém typu rozhodne pouze jeden z nich. Například v jazyce AppleScript se typ výsledné hodnoty stanoví podle typu operandu nejvíce vlevo.

Bezpečné typování

Třetí způsob kategorizace typového systému programovacího jazyka se zaměřuje na bezpečné typové operace a konverze. Za „typově bezpečný“ se považuje jazyk, který nedovoluje operace nebo konverze vedoucí k chybám. Někdy se používá termín „paměťově bezpečný“, kam spadají jazyky zamezující nedefinovaným operacím (kontrolují např. rozsah pole, aby nedošlo k přístupu mimo jeho hranice a porušení ochrany paměti).

var x = 5;
var y = "37";
var z = x + y;

Uvedené proměnné z může ale nemusí být přiřazen datový typ, jazyk definuje výsledek konkrétně a program může běžet bez pádu a aniž by přiřadil chybnou hodnotu. Tím je zajištěna typová bezpečnost, avšak kdyby byla hodnota proměnné y řetězec, který nelze převést na číslo, bude výsledek nedefinovaný a program může vygenerovat nežádoucí výsledky.

Automatické odvozování typů

Mnoho jazyků má silnou typovou kontrolu bez vyžadování explicitního uvádění typů proměnných. Například ve Swiftu lze napsat

let x = 1234
let s = "abcd"

přičemž překladač deklarovaným proměnným automaticky přiřadí odpovídající konkrétní typy. Jazyky s generickými typy mívají také automatické odvozování typových parametrů, takže vývojář nemusí uvádět při instanciaci funkce nebo metody příslušné typy.[1]

Reference

  1. Algoritmus pro inferenci typových parametrů

Literatura

  • VAVREČKOVÁ, Šárka. Programování překladačů. Opava: Slezská univerzita v Opavě, 2008. ISBN 978-80-7248-493-5. Kapitola Sémantická analýza, s. 111–116.
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.