Historie a vývoj jazyka C (od C až po C#)

(kolokviální práce do předmětu Historie a vývojové trendy ve výpočetní technice, Pavel Černohorský, 2003)

Programovací jazyk C

Vraťme se nyní na chvilku do šedesátých let minulého století, do doby kdy v USA probíhaly veliké změny. Nás ale budou zajímat události jiné, které určitě nebyly tolik známy mezi veřejností, ale které přesto možná nepřímo ovlivnily vývoj společnosti, ve které dnes žijeme. Dalo by se říct, že se v téhle době totiž začal rodit programovací jazyk, který ve značné míře určil směr, kterým se bude ubírat programování a tím i způsob využití počítačů, které nesporně ovlivňují život každého z nás, po několik dalších dekád.
Počátky jazyka C byly neoddělitelně spjaty s operačním systémem UNIX, který vznikl roku 1968 v Bellových laboratořích v Murray Hill, New Jersey. Brzy po vzniku UNIXu začal Ken Thompson na počítači PDP-7 firmy DEC vytvářet jednoho z předchůdců jazyka C - programovací jazyk B.
Podívejme se ale ve stručnosti ještě kousek víc do historie na větší část vývojové větve „Céčka“. V roce 1963 byl na univerzitách Cambridge a University of London vytvořen jazyk CPL (oficiálně Combined Programming Language, neoficiálně však prý zkratka původně vznikla ze slov "Cambridge Plus London"), který částečně vycházel z Algolu 60. Byl však prý příliš složitý k naučení i k implementaci a tak byl proto o čtyři roky později, roku 1967, na univerzitě v Cambridge zjednodušen Martinem Richardsem s cílem zachovat jeho dobré vlastnosti a vznikl tak jazyk BCPL (Basic Combined Programming Language). Tento jazyk byl beztypový (typ byl určován podle kontextu využití proměnné). Pro ilustraci přikládám ukázku kódu pro výpočet faktoriálů prvních 10ti přirozených čísel v jazyce BCPL:
// FACTORIAL
GET "LIBHDR"
LET START () BE $(
LET F(N) = N=0 -> 1, N*F(N-1)
FOR I = 1 TO 10 DO WRITEF("F(%N), = %N*N", I, F(I))
FINISH
$)
(kód je převzat z otevřeného archivu konferencí spolku Lysator, The Academic Computer Society při Linköping University ve Švédsku [6] - kód psal Alan Watson)

A nyní se konečně dostáváme k programovacímu jazyku B, který byl vyvinut, jak již bylo předesláno, Kenem Thompsonem z Bellových laboratoří. Tento jazyk byl stejně jako jeho předchůdce beztypový a stejně jako jeho předchůdce trpěl několika významnými neduhy. Jednou z největších bylo, že soustavným zjednodušováním vznikl jazyk limitovaný, vhodný pouze pro řešení určitých problémů. Později, po příchodu počítače PDP-11 byl jazyk přeimplementován spolu s UNIXem pro tento stroj (pro srovnání s dnešními počítači, přestože byl PDP-11 o hodně lepší než předcházející PDP-7, měl pouze 25KB paměti, ze kterých systém využíval 16KB, a byl v něm jeden pevný disk velikosti 512KB). Při tehdejším přenosu UNIXu z PDP-7 na PDP-11 byl vážným problémem fakt, že UNIX byl napsán v jazyce nízké úrovně (přesněji jazyce symbolických instrukcí) a byl proto špatně přenositelný. Byly proto návrhy pro přepis UNIXu do jiného jazyka (B byl kandidátem), ale tyto myšlenky byly smeteny ze stolu kvůli tomu, že B byl pomalý a nevhodný pro psaní operačního systému (problémy s adresováním po slovech, ne po bytech jako počítač PDP-11). Toto byly rámcově nejdůležitější důvody pro počátek práce na následovníku jazyka B v roce 1971 - ne zrovna nápaditě, však ve shodě s vývojem, pojmenovaném C.
Autorem jazyka C se stal Dennis M. Ritchie [13] z Bellových laboratoří. Roku 1972 tedy světlo světa spatřil nový programovací jazyk, který se navrátil k některým obecným principům CPL, které byly v BCPL a B ztraceny. Byl tedy vytvořen jazyk s bohatými datovými typy, přičemž zůstala zachována jednoduchost a přímý přístup k hardware. Pro ilustraci rozdílů jazyků BCPL, B a C zde ještě uvedu jeden kousek kódu napsaný v těchto třech programovacích jazycích (kód byl převzat beze změny, pozornější z vás si však jistě všimnou, že obsahuje chybu a nepočítá to, co o sobě hlásá, pro ilustraci rozdílů mezi jazyky však postačí):

kód psaný v jazyce C:
/* infact -- initializes elements from fact[0] = 0! up to
* fact[n] = n!. Returns n!. */

float infact (n) int n;
/* or, of course, the newer float infact (int n) */
{
float f = 1;
int i;
extern float fact[];

for (i = 0; i <= n; ++i)
fact[i] = f *= i;

return f;
}

#define TOPFACT 10
float fact[TOPFACT+1];

kód psaný v jazyce B:
infact (n)
{
auto f, i, j; /* no initialization for auto variables */
extrn fact; /* "What would I do differently if designing
* UNIX today? I'd spell creat() with an e."
* -- Ken Thompson, approx. wording */

f = 1.; /* floating point constant */
j = 0.;
for (i = 0; i <= n; ++i) {
fact[i] = f =#* j; /* note spelling =#* not #*= */
j =#+ 1.; /* #+ for floating add */
}

return (f); /* at least, I think the () were required */
}

TOPFACT = 10; /* equivalent of #define, allows numeric values only */
fact[TOPFACT];

kód psaný v jazyce BCPL:
MANIFEST ${ TOPFACT = 10 $)   // Equivalent of "const int TOPFACT = 10"
LET infact (n) = VALOF
$(
LET f, j = 1., 0.

FOR i = 0 TO n // Declares i for the next block only
$(
f #*:= j; // := is assign, = is compare
fact!i := f; // assignment doesn't return a value
j #+:= 1.
$)
RESULTIS f
$)
AND fact = VEC TOPFACT; // As in B, allocates 0 to TOPFACT
(kódy jsou převzaty z otevřeného archivu konferencí spolku Lysator, The Academic Computer Society při Linköping University ve Švédsku [6] - kód pro C a B psal Mark Brader, kód pro BCPL psal Clive D.W. Feather)

Dennis Ritchie byl ve své době znám jako systémový programátor, pracoval například na vývoji operačních systémů a na překladačích programů. Není proto divu, že navrhl jazyk C jako relativně nízkoúrovňový jazyk, vhodný jak k přesnému vyjádření algoritmu a k systémovému programování, tak jako jazyk schopný abstrahovat od počítačové architektury. Není mým cílem vypisovat všechny vlastnosti jazyka C, avšak zmíním alespoň ty základní:
Jazyk C se stal po velmi krátké době natolik populární, že do něj byl přepsán téměř celý UNIX a další programy. Zároveň začaly vznikat překladače nového jazyka pro různý v té době dostupný hardware. To s sebou však neslo problémy - jazyk C nebyl nijak standardizován a mnoho  překladačů si při jeho implementaci přidalo různé další specifické vlastnosti. Tím ale vznikly potíže s přenositelností kódu, jednou z velkých předností „Céčka“.
V průběhu 70tých let až do roku 1978 se jazyk C vyvíjel do formy, kterou bychom dnes pravděpodobně nazvali „tradiční C“, někdy též „pre-ANSI C“. Ve zmiňovaném roce vydalo nakladatelství Prentice-Hall knihu Briana Kernighana a Dennise Ritchieho The C Programming Language, později též běžně označovanou „K&R C“. Dalo by se říct, že se tato kniha stala první neoficiální „normou“ jazyka C a tak překladače vytvořené po jejím uveřejnění (a upravené starší překladače) již obsahovaly všeobecně sjednocené nové vlastnosti. Pro zajímavost uvedu, že v této době obsahoval jazyk 27 klíčových slov.
K další významné změně v rysech jazyka a k dalšímu sjednocování došlo roku 1982, kdy Americký institut národních standardů (American National Standard Institute - ANSI [10]) ustanovil komisi X3J11 pro standardizaci jazyka C, která měla za úkol sestavit normu pro jazyk i jeho knihovny (jazyk sám o sobě je totiž, dalo by se říct, velmi jednoduchý, jeho síla a schopnosti spočívají právě v bohatosti knihoven) a vytvořit tak jednoznačnou a na hardwaru nezávislou definici jazyka. A tak byla roku 1989 formálně přijata norma American National Standard X3.159-1989, spíše známá pod názvem ANSI C. Tato norma si kladla za cíl ujasnit některé nepřesnosti jazyka vzniklé při rozvoji jednotlivých kompilátorů, rozšířit jazyk o nové vlastnosti, které se od roku 1978 objevily a přitom měla být zachována jednoduchost jazyka. Požadavky byly v podstatě splněny, pro zajímavost dodám, že tato verze jazyka již obsahovala 47 klíčových slov. Norem ANSI bylo během let více, ale tato je nejznámější a nejpoužívanější z nich. Byla zároveň brzy pro svém vzniku převzata organizací ISO (International Organization for Standardization [11]) i jako vzor pro evropskou normu označovanou ISO/IEC 9899-1990. V současné době nejnovější normou je ISO/IEC 9899:1999 (pro zajímavost má norma 550 stran a lze se na ni podívat například na adrese [12]), bohužel trvalo poměrně dlouho, než ji nejčastěji rozšířené překladače začaly podporovat a ještě dnes se můžeme setkat s neúplnou či špatnou podporou této specifikace. V době psaní tohoto pojednání (listopad 2003) se však již dá programovat podle této normy a nové překladače by neměly mít větší problémy.

Programovací jazyk C++

Teď, když jsme se podrobněji seznámili s jednou z legend počítačového světa, která žije již třicet let (což je v oblasti výpočetní techniky opravdu velmi dlouhá doba), můžeme se podívat i na mladšího bratříčka opěvovaného „Céčka“. Pojmenování mladší bratříček se však pro jazyk C++ moc nehodí, možná spíše mladší, ale „chytřejší a tlustší“ bratříček. S jistou nepřesností by se totiž dalo říct, že je spíše nadmnožinou jazyka C. Kromě spousty vylepšení zavádí jedno hlavní, které z něj dělá skoro až jiný programovací jazyk - možnost objektového přístupu.
Jazyk C++ je tedy odvozen z velké části z jazyka C, dále pak třeba z jazyka Algol 68 (přetěžování operátorů, deklarování proměnné blízko jejímu prvnímu využití), z jazyka Simula 67 (princip tříd, virtuálních funkcí) a z dalších.
Autorem C++ se stal Bjarne Stroustrup z Bellových laboratoří, který na jazyce začal pracovat na počátku 80tých let. Původně byl jazyk C++ vyvíjen pro vyřešení jedné konkrétní simulace s velice specifickými požadavky, které napovídaly spíše na využití jiného jazyka než C. Do roku 1983 přidal Stroustrup další vlastnosti do jazyka C a vzniklo tak něco, co on sám nazval "C with Classes" (C s třídami). Roku 1983 nový jazyk poprvé opustil prostory Bellových laboratoří a na svou pouť světem se vydal pod označením C++, které bylo tehdy prvně použito.
A jak to bylo s dalším vývojem a standarty? Nedlouho po publikování jazyka, přesněji v říjnu 1985 vyšla také kniha Bjarnea Stroustrupa The C++ Programming Language (za povšimnutí stojí analogie se jménem knihy Kernighana a Ritchieho) a došlo k prvnímu uvolnění komerčního překladače jazyka C++. Do léta roku 1987 pak procházel jazyk přirozeným vývojem a úpravami, přesto však nedošlo ke ztrátě zpětné kompatibility s C a tak mohli programátoři celého světa dále využívat milióny svých už jednou těžce napsaných řádků kódu. V roce 1989 byl, jak už bylo zmíněno v předcházející kapitole, standardizován jazyk C, což posloužilo zároveň jako příspěvek k přesnému ujasnění strukturovanosti C++. Od roku 1990 začala pracovat komise ANSI institutu a organizace ISO pod označením X3J16 (jejímž členem i sám tvůrce jazyka) na vytvoření standardu s cílem ujednotit vlastnosti jazyka a umožnit tak vznik překladačů schopných bezpečně přeložit přenositelný kód. Práce komise trvala větší část 90tých let, kdy zažilo C++ dobu svého největšího rozmachu a stalo se nejpoužívanějším jazykem pro vývoj aplikací této doby. Koncept standardu ANSI byl nakonec vydán roku 1997 a vlastní norma byla schválena i organizací ISO jako ISO/IEC 14882:2003. Někdy je norma souhrnně označována jako ANSI/ISO C++. V současné době je nejnovější dostupná verze normy ISO/IEC 14882:2003, vydaná tento rok.
Ještě bych si zde dovolil odkázat na stránky Bjarnea Stroustrupa - Stroustrup: FAQ [14], kde vysvětluje některé své zajímavé názory a postoje ohledně C++, jeho minulosti i budoucnosti ve světě dalších novějších jazyků (dozvíte se například názory Bjarnea na garbage collection (automatický management paměti použitý například v platformě .NET a tím v jazyku C#), nebo o tom, že Bjarne vůbec neočekával jakýkoliv úspěch svého jazyka).

Programovací jazyk C#

A jak začít pojednání o historii jazyka C# (čteno [cí-šarp])? Předchozí kapitolu o C++ jsem začal srovnáním s C, teoreticky bych tedy měl teď začít srovnávat jazyka C# s jazykem C++, ale nebude tomu tak. Kdybych se snažil srovnat jazyk C# a C++, bylo by to jako srovnávat dva úplně různé a skoro nijak nesouvisející jazyky (nepočítáme-li jméno), ať si firma Microsoft, tvůrce C#, tvrdí co chce (označuje totiž C# za vývojové pokračování C a C++, proto je C# také zařazen do tohoto pojednání). C# toho má totiž s C++ společného mnohem méně, nežli mělo kdysi C++ s C. C++ bylo, jak bylo již řečeno, nadmnožinou C, avšak kompilátorem C# byste program psaný v C++ rozhodně nezkompilovali. Pokud bych měl jazyk C# k něčemu přirovnat, srovnal bych ho pravděpodobně s Javou, které měl také, jak se říká, být přímým konkurentem (marketing společnosti Microsoft zde opravdu výrazně zasáhl, velmi brzy po uvolnění C# byly k dispozici i nástroje pro konverzi zdrojových kódů z Javy do C#).
Ale nyní již k vlastní historii C#, která je neoddělitelně spjata s platformou Microsoft .NET. Vraťme se do roku 1993, kdy byly uvedeny modely COM (Component Object Model - softwarová architektura umožňující vystavět aplikace z binárních komponent) a DCOM (Distributed Component Object Model - protokol umožňující komunikovat softwarovým komponentám přes síť (včetně internetu pomocí HTTP protokolu)). Tyto dva modely se postupem času roku 1997 spojily do COM+, což bylo rozšíření původního COM rozhraní. Umožňovalo softwarovým komponentám psaným v různých jazycích, aby spolu komunikovaly. Tato myšlenka byla použita roku 1999, kdy se Microsoft zmiňuje o technologii .NET - platformě skládající ze z tak zvaného CLR (Common Language Runtime) a z knihovny tříd systému .NET Framework (někdy nazývaných Base Class Library - BCL). CLR má být společným běhovým prostředím pro programy psané v různých jazycích, díky CLR spolu mohou jednotlivé části programu (nebo celé programy) navzájem spolupracovat, přestože byly napsány každý v jiném programovacím jazyce. Toho je dosaženo tím, že aby programovací jazyk mohl produkovat kód kompatibilní s CLR, musí vyhovovat specifikacím CLS (Common Language Specifications). A zde právě přichází na řadu C#. Je to první jazyk navržený přesně podle systému CLS a tím umožňuje asi nejlépe využít veškeré jeho možnosti. Přestože s jistými úpravami vyhovuje specifikaci CLS více programovacích jazyků, které jsou pro prostředí .NET upravovány, C# je tomuto prostředí šitý přesně na míru. Pokud kompilujete program  v C#, výsledkem není přímo strojový kód proveditelný procesorem, ale kód v jazyku MSIL (Microsoft Intermediate Language), který je teprve pomocí CLR přeložen do nativního kódu procesoru. Nejedná se tedy o jazyk interpretovaný, jako třeba Java, ze které se C# hodně inspiroval, ale ve výsledku přímo o spustitelný kód, i když generovaný automaticky až těsně před spuštěním programu.
Z hlediska vývoje, bych teď uvedl několik dat. Dne 22. června 2000 uvedl Bill Gates na konferenci Forum 2000 svou vizi platformy .NET. (přestože první beta verze byla hotová již v roce 1999). O 4 dny později, tj. 26. června 2000, ohlašuje Microsoft uvedení jazyka C# a počátek jeho standardizace. V první polovině roku 2001 je dokončení kompilátoru pro jazyk C# a celá platforma .NET 1.0 je oficiálně uvolněna pro veřejnost 15. ledna 2002 (partnerům MS byla dostupná již mnohem dříve, včetně všech vývojových beta verzí). Finální verze normy ISO pro jazyk C# potom byla publikována 2. dubna 2003 jako ISO/IEC 23270. V současné době jsou k dispozici kompilátory jazyka C# verze 1.1 (např. Visual Studio 2003) a k nahlédnutí na stránkách společnosti Microsoft je návrh specifikace jazyka C# 2.0, který má obsahovat spoustu nových vlastností, jako jsou například Generika (obdoba Templates v C++). Koho by tato problematika zajímala více, doporučuji nahlédnout na MSDN (Microsoft Development Network) [9].
Nový přístup k překladu programu do strojového kódu přímo před jeho spuštěním má své příznivce i odpůrce a teprve čas ukáže, kdo měl pravdu. Ale prozatím vše nasvědčuje tomu, že se platforma .NET a s ní i jazyk C# rozšíří. Platformu začaly totiž podporovat i firmy jako Borland (oznámil podporu v únoru roku 2002) a již vydal (velmi nedávno - 6. června 2003) vlastní verzi vývojového prostředí pro jazyk C#. Zároveň probíhá převod platformy .NET a jazyku C# na OS Linux - za zmínku stojí např. projekt Mono [15].
Pokud bude vývoj pokračovat současným tempem, jazyk C# se asi brzy dostane do povědomí jako silný nástroj pro vývoj aplikací všeho druhu a možná právě jemu bude patřit budoucnost.


Použité zdroje:
[1] - Kolektiv autorů: Programování v jazyku C  (JZD Agrokombinát Slušovice, 1987)
[2] - Samuel P. Harbison a Guy L. Steele Jr.: Referenční příručka jazyka C  (Science, 1996)
[3] - William H. Murray & Chris H. Pappas: Microsoft C/C++ 7: The complete Reference  (McGraw-Hill, 1992)
[4] - Dr. Harvey M. Deitel & Paul J. Deitel: C How to Program -  Third Edition  (Deitel & Associates, Inc., 2001)
[5] - Tom Archer: Myslíme v jazyku C#  (Grada, 2001)
[6] - Lysator, The Academic Computer Society - http://www.lysator.liu.se
[7] - HitMill (IT Training for Students and Developers) - http://www.hitmill.com
[8] - CplusPlus.com - http://www.cplusplus.com
[9] - MSDN (Microsoft Development Network) - http://msdn.microsoft.com

Zajímavé odkazy:
[10] - American National Standard Institute - http://www.ansi.org
[11] - International Oraganization for Standardization - http://www.iso.org
[12] - ISO/IEC 9899:1999 - http://www.cl.cam.ac.uk/~mgk25/volatile/ISO-C-FDIS.1999-04.pdf
[13] - Dennis M. Ritchie Home Page - http://www.cs.bell-labs.com/who/dmr/index.html
[14] - Stroustrup: FAQ - http://www.research.att.com/~bs/bs_faq.htm
[15] - The Mono Project - http://www.go-mono.com