DODATEK A PRZEWODNIK JĘZYKA C_______
int max(a, b, c) int a, b, c;
/* .» *1
gdzie deklaratorem jest teraz int max(a, b, c), a int a, b, c; jest listą deklaracji parametrów.
Deklaracje zewnętrzne opisują właściwości obiektów, funkcji i innych identyfikatorów. Pojęcie „zewnętrzne” odnosi się do ich położenia na zewnątrz wszystkich funkcji i nie jest bezpośrednio związane ze słowem kluczowym extem; klasę pamięci dla obiektów zadeklarowanych na zewnątrz można pominąć lub można podać jako extern lub static.
W tej samej jednostce tłumaczenia może wystąpić kilka zewnętrznych deklaracji tego samego identyfikatora pod warunkiem, że są one zgodne pod względem typu i łączności oraz że istnieje co najwyżej jedna definicja tego identyfikatora.
Dwie deklaracje tego samego obiektu lub funkcji uważa się za zgodne ze względu na typ, jeśli spełniają warunki opisane w p. A8.10. Ponadto, jeśli deklaracje się różnią, ponieważ jeden z typów jest niekompletną strukturą, unią lub wyliczeniem (p. A8.3), a drugi jest odpowiednim kompletnym typem z tą samą etykietką, to te typy uważa się za zgodne. Uważa się za zgodne również typy, z których jeden jest niekompletnym, drugi zaś kompletnym typem tablicowym (p. A8.6.2), i które poza tym są identyczne. Wreszcie, jeśli jeden z typów określa funkcję w starym stylu, a drugi funkcję w nowym stylu z deklaracjami parametrów, a poza tym identyczną, to te typy uważa się za zgodne.
Jeśli pierwsza z zewnętrznych deklaracji funkcji lub obiektu zawiera specyfikator static, to identyfikator ma „łączność wewnętrzną”; w przeciwnym przypadku ma „łączność zewnętrzną”. Łączność identyfikatorów będzie opisana w p. Al 1.2.
Zewnętrzna deklaracja obiektu jest jego definicją, jeśli zawiera inicjowanie. Zewnętrzna deklaracja bez inicjowania i bez specyfikatora extern nazywa się definicję prób-ną. Gdy w jednostce tłumaczenia pojawi się definicja obiektu, wówczas jego wszystkie definicje próbne traktuje się jak zbędne deklaracje. Jeśli w jednostce tłumaczenia w ogóle nie wystąpi definicja dla tego obiektu, to jego wszystkie definicje próbne stają się pojedynczą definicją z wartością początkową równą zero.
A11 ZASIĘG I ŁĄCZNOŚĆ NAZW
Każdy obiekt musi mieć dokładnie jedną definicję. Dla obiektów z łącznością wewnętrzną ta zasada odnosi się oddzielnie do każdej jednostki tłumaczenia, ponieważ obiekty z łącznością wewnętrzną są unikalne w ramach jednostki tłumaczenia. Dla obiektów z łącznością zewnętrzną ta zasada odnosi się do całego programu.
Chociaż w pierwszym wydaniu książki zasadę pojedynczej definicji sformułowano nieco inaczej, była ona w praktyce identyczna z powyższą. W niektórych implementacjach zasadę tę nieco złagodzono, rozszerzając znaczenie definicji próbnej. Alternatywna zasada, obowiązująca zwykle w systemach UNIX i powszechnie traktowana jako rozszerzenie Standardu, mówi, że wszystkie definicje próbne obiektów z łącznością zewnętrzną są rozpatrywane łącznie dla wszystkich jednostek tłumaczenia, nie zaś dla każdej jednostki oddzielnie. Jeśli gdziekolwiek w programie wystąpi definicja obiektu, to jego definicje próbne po prostu stają się deklaracjami; jeśli jednak definicja nie wystąpi, to wszystkie definicje próbne stają się pojedynczą definicją z wartością początkową równą zero.
Cały program nie musi być tłumaczony w tym samym czasie: tekst źródłowy można trzymać w kilku plikach zawierających jednostki tłumaczenia, a uprzednio przetłumaczone podprogramy można dołączać z bibliotek. Komunikacja między funkcjami programu może być realizowana zarówno przez wywołania, jak i przez manipulowanie danymi zewnętrznymi.
Mamy zatem do rozważenia dwa rodzaje zasięgu nazw. Pierwszy, leksykalny zasięg identyfikatora, dotyczy tego fragmentu programu, w którym są znane właściwości identyfikatora. Drugi, związany z obiektami i funkcjami o łączności zewnętrznej, rozstrzyga o powiązaniach między identyfikatorami pochodzącymi z oddzielnie kompilowanych jednostek tłumaczenia.
Identyfikatory należą do kilku nie związanych ze sobą przestrzeni nazw; ten sam identyfikator może być użyty w kilku różnych kontekstach, nawet w tym samym zasięgu, jeżeli tylko te konteksty wyznaczają różne przestrzenie nazw. Takimi przestrzeniami są: obiekty, funkcje, nazwy typedef i stałe wyliczeń; etykiety; etykietki struktur, unii i wyliczeń; składowe oddzielnie dla każdej struktury i unii.
303