GNU C -=-=-=- while (*p++ = *q++); -- Dennis M. Ritchie Většina lidí čte název Borland C compiler jako překladač jazyka C od Borlandu. Martin Mareš si myslí, že tomu tak není a že je třeba název jinak ozávorkovat a ve skutečnosti to je překladač Borland C, kde Borland C je jazyk, jehož syntax není dopusud známa. O GNU C compileru platí to samé. Syntax GNU C ale známa je a ví se o ní, že to je nadmnožina Ansi C a má některé užitečné rošíření, které se hodí hlavně, když chcete mít program hodně rychlý. Inline funkce versus builtiny Jazyk C se kompiluje jen do malé podmnožiny instrukcí počítače. Standard říká, že ostatní (jako třeba in, out, nebo nová skvělá sada MMX :) jsou příliš závislé na architektuře, než aby se dávaly do jazyka a jediná správná cesta je volat je z knihovních funkcí, které jsou psané v assembleru. Bohužel často se tyto funkce používají ke zrychlení výsledku. Existuje například mnoho chytrých cest, jak kopírovat paměť (rep movsb na xt-286, po 32bitových blocích na 386-486, přes koprocesor na pentiu..), které ani ten nejchytřejší překladač z jednoduchého for cyklu nevymyslí. Nebo jsou situace, kdy takové instrukce musíte používat často (třeba out a in v hardwarových driverech) a jejich volání jako funkcí zdržuje, zvětšuje kód a přináší další potíže. Jedna odpověď na to je built-in. Do překladače se zaintegrují nejčastější takové případy (jako je memset, outb...) a ten potom umí sám generovat optímální kód. Takových funkci je hodně (koukněte se do string.h a math.h například sin, cos, abd, fabs, strcpy, strdup, memcpy, memmove a takhle bych mohl pokračovat ještě hodně dlouho) řádově se to pohybuje podle mého názoru ve stovkách. Jednotlivé překladače se často triumfují v tom, kdo má více takových funkcí integrovaných, a některé - jako třeba Watcom C - jich umí opravdu hodně. Na druhou stranu je to jenom jakási ošklivá výpomoc, která funguje jen v nejčastějších připadech. Představte si třeba, že jste vymysleli bezvadnou cestu jak implementovat násobení ve fixedpointu a chcete to použít ve svých programech. V knihovně taková funkce ale není a tak ani compiler ji nemá jako builtin. A máte smůlu. Takových případů jsou doslova tisíce - například memset pro 16ti a 32 bitová čísla, který se hodí pro truecolor apod. Navíc se to rozchází s filozofií C jako minimálního ale maximálně rychlého jazyka. V GCC vývojáři zvolili jinou cestu. Builtin je opravdu jenom několik základních funkcí (abort, abs, alloca, cos, exit, fabs, ffs, labs, memcmp, memcpy, sin, sqrt, strcmp, strcpy, strlen) a to hlavně proto, že jsou natolik časté, že je třeba nejenom generovat optimální kód bez callu ale třeba i předpočítávat jejich výsledek pro konstantu a dělat další podobné optimalizace specifické pro danou funkci. Místo toho ale do GCC přidali několik rozšíření tak, aby běžný programátor, aniž by hackoval překladač, si mohl vytvořit svoje vlatsní funkce, které se chovají jako builtin.Tyto rozšíření jsou ale navíc tak obecné a šikovné, že se používají i v mnoha jiných případech. Je to: * Rozšířená syntaxe asm * extern inline funkce stejně rychlé jako makra * __builtin_constant_p * atributy funkcí Tak to je asi to nejdůležitější. S těmito rozšířeními jde implementovat celkem dost věcí. Abyste měli co studovat, ještě přidám inline verzi string.h a math.h. Ty můžete includovat i do vlastních programů, pokud chcete, aby na x86 běžely rychleji. Rozšížení šikovná hlavně pro optimalizaci Když se tak dívám, co všechno jsem už napsal a popsal jenom čtyři tak z cca 80 rozšížení, vezmu to už jenom krátce a neúplně. * Rozšíření (nejenom) pro psaní maker * Explicitní určování regitrů pro proměné Ostatní Gcc má mnoho dalších rozšížení jako je například aritmetika s labely a ukazately na funkce, goto *ukazatel, intervaly pro case (case 1 ... 9:), long long (64 bit integer), long double (jako extended v Pascalu), vnořené funkce (jako v Pascalu), atributy pro proměné a typy určující zarovnávání, pakování struktur apod, konstrukce volání funkce parametr po parametru, // komentáře a mnoho dalších více či méně užitečných věcí. Možná o nich jednou také napíšu. výheň