[ Pobierz całość w formacie PDF ]
prototypy funkcji oferowanych przez przeróżne biblioteki są umieszczane w ich plikach
nagłówkowych, zaś zadanie programisty-użytkownika ogranicza się jedynie do włączenia
tychże nagłówków do własnego kodu.
Kompilator wykonuje zatem sporą część pracy za nas. Warto jednak przynajmniej znać te
najczęściej wykorzystywane konwencje wywołania, a nie jest ich wcale aż tak dużo.
Poniższa lista przedstawia je wszystkie:
cdecl - skrót od C declaration ( deklaracja C ).. Zgodnie z nazwą jest to domyślna
konwencja wywołania w językach C i C++. W Visual C++ można ją jednak jawnie
określić poprzez słowo kluczowe __cdecl. Parametry są w tej konwencji
przekazywane na stos w kolejności od prawej do lewej, czyli odwrotnie niż są
zapisane w deklaracji funkcji
stdcall - skrót od Standard Call ( standardowe wywołanie ). Jest to konwencja
zbliżona do cdecl, posługuje się na przykład tym samym porządkiem odkładania
parametrów na stos. To jednocześnie niepisany standard przy pisaniu kodu, który
w skompilowanej formie będzie używany przez innych. Korzysta z niego więc
chociażby system Windows w swych funkcjach API.
W Visual C++ konwencji tej odpowiada słowo __stdcall
fastcall ( szybkie wywołanie ) jest, jak nazwa wskazuje, zorientowany na szybkość
działania. Dlatego też w miarę możliwości używa rejestrów procesora do
przekazywania parametrów funkcji.
Visual C++ obsługuję tą konwencję poprzez słówko __fastcall
pascal budzi słuszne skojarzenia z popularnym ongiś językiem programowania.
Konwencja ta była w nim wtedy intensywnie wykorzystywana, lecz dzisiaj jest już
przestarzała i coraz mniej kompilatorów (wszelkich języków) wspiera ją
thiscall to specjalna konwencja wywoływania metod obiektów w języku C++.
Funkcje wywoływane z jej użyciem otrzymują dodatkowy parametr, będący
wskaznikiem na obiekt danej klasy94. Nie występuje on na liście parametrów w
deklaracji metody, ale jest dostępny poprzez słowo kluczowe this. Oprócz tej
szczególnej właściwości thiscall jest identyczna z stdcall.
Ze względu na specyficzny cel istnienia tej konwencji, nie ma możliwości
zadeklarowania zwykłej funkcji, która by jej używała. W Visual C++ nie
odpowiada jej więc żadne słowo kluczowe
A zatem dotychczas (nieświadomie!) używaliśmy tylko dwóch konwencji: cdecl dla
zwykłych funkcji oraz thiscall dla metod obiektów. Kiedy zaczniemy naukę
programowania aplikacji dla Windows, wtedy ten wachlarz zostanie poszerzony. W
każdym przypadku składnia wywołania funkcji w C++ będzie jednak identyczna.
94
Jest on umieszczany w jednym z rejestrów procesora.
Podstawy programowania
316
Nazwa funkcji
To zadziwiające, że chyba najważniejsza dla programisty cecha funkcji, czyli jej nazwa,
jest niemal zupełnie nieistotna dla działającej aplikacji!& Jak już bowiem mówiłem,
widzi ona swoje funkcje wyłącznie poprzez ich adresy w pamięci i przy pomocy tych
adresów ewentualnie wywołuje owe funkcje.
Można dywagować, czy to dowód na całkowity brak skrzyżowania między drogami
człowieka i maszyny, ale fakt pozostaje faktem, zaś jego przyczyna jest prozaicznie
pragmatyczna. Chodzi tu po prostu o wydajność: skoro funkcje programu są podczas
jego uruchamiania umieszczane w pamięci operacyjnej (można ładnie powiedzieć:
mapowane), to dlaczego system operacyjny nie miałby używać wygenerowanych przy
okazji adresów, by w razie potrzeby rzeczone funkcje wywoływać? To przecież proste i
szybkie rozwiązanie, naturalne dla komputera i niewymagające żadnego wysiłku ze
strony programisty. A zatem jest ono po prostu dobre :)
Rozterki kompilatora i linkera
Jedynie w czasie kompilacji kodu nazwy funkcji majÄ… jakieÅ› znaczenie. Kompilator musi
bowiem zapewnić ich unikalność w skali całego projektu, tj. wszystkich jego modułów.
Nie jest to wcale proste, jeżeli przypomnimy sobie o funkcjach przeciążanych, które z
założenia mają te same nazwy. Poza tym funkcje o tej samej nazwie mogą też
występować w różnych zakresach: jedna może być na przykład metodą jakiejś klasy, zaś
druga zwyczajnÄ… funkcjÄ… globalnÄ….
Kompilator rozwiÄ…zuje te problemy, stosujÄ…c tak zwane dekorowanie nazw.
Wykorzystuje po prostu dodatkowe informacje o funkcji (jej prototyp oraz zakres, w
którym została zadeklarowana), by wygenerować jej niepowtarzalną, wewnętrzną nazwę.
Zawiera ona wiele różnych dziwnych znaków w rodzaju @, ^, ! czy _, dlatego właśnie jest
określana jako nazwa dekorowana.
Wywołania z użyciem takich nazw są umieszczane w skompilowanych modułach. Dzięki
[ Pobierz całość w formacie PDF ]