Podrozdziały


1.1 Kompilatory

Język C++ należy do języków kompilowanych (tak jak Fortran, Ada, Pascal i wiele innych).

W odróżnieniu np. od Javy, wynikiem kompilacji nie jest niezależny od platformy kod bajtowy (ang. byte-code), ale plik wykonywalny (ang. executable), czyli taki, który zawiera kod programu w języku maszynowym odpowiednim dla platformy (czyli systemu operacyjnego i procesora naszego komputera). Tak więc dla uruchomienia programu nie jest konieczne specjalne środowisko uruchomieniowe (jak maszyna wirtualna Javy czy interpreter Pythona) — wykonanie odbywa się bezpośrednio pod kontrolą systemu operacyjnego, choć zwykle do jego działanie są konieczne pewne pliki biblioteczne. Ponieważ w czasie wykonania nie jest już dokonywana żadna dodatkowa translacja, programy w C/C++ są zwykle szybkie (programy w C są prawie tak szybkie jak programy w Fortranie, programy w C++ są zwykle, choć nie zawsze, nieco wolniejsze).

Tak naprawdę kompilacja jest tylko jednym z etapów procesu wytwarzania pliku wykonywalnego. Dla uproszczenia jednak nazywać tu będziemy kompilacją cały proces prowadzący od pliku źródłowego do pliku wykonywalnego.

W rzeczywistości potrzebny jest jeszcze na przykład preprocesor i tzw. linker (zwany też konsolidatorem albo programem łączącym). W dużym skrócie, rolą linkera jest polączenie w jeden plik wykonywalny wielu plików otrzymanych w wyniku kompilacji poszczególnych plików źródłowych, których może być wiele i mogą być kompilowane osobno i w różnym czasie.

Zaletą tego podejścia jest duża szybkość wykonywania kodu zawartego w pliku wykonywalnym. Kompilacji oczywiście nie trzeba powtarzać przed każdym uruchomieniem programu: raz utworzony plik wykonywalny można zlecać systemowi operacyjnemu do wykonania, czyli uruchamiać, dowolną liczbę razy. Wadą języków w pełni kompilowanych, jak C++, jest, jak wspomnieliśmy, uzależnienie kodu wykonywalnego od platformy. Oczywiście sam tekst programu (źródło, ang. source) jest niezależny od platformy, jeśli trzymamy się w nim ściśle standardu języka C++ i nie stosujemy żadnych specyficznych dla danego kompilatora rozszerzeń.


Co dla nas z tego wszystkiego wynika to to, że potrzebujemy kompilatora (wraz z linkerem, preprocesorem, bibliotekami itd.). Dla tych, którzy nie mają zainstalowanego na swoim komputerze kompilatora C++ (albo mają, ale o tym nie wiedzą), podamy więc parę szczegółów dotyczących jego instalacji. Do jej sprawdzenia możemy potem użyć następującego programu:


P1: testInst.cpp     Test instalacji

      1.  /*
      2.   * Test instalacji. Program powinien wypisać nazwy
      3.   * 4 języków programowania w porządku alfabetycznym.
      4.   */
      5.  #include <vector>
      6.  #include <algorithm>
      7.  #include <iostream>
      8.  #include <string>
      9.  using namespace std;
     10.  
     11.  int main() {
     12.      vector<string> vs;
     13.      vs.push_back("Python"); vs.push_back("Haskell");
     14.      vs.push_back("C++");    vs.push_back("Java");
     15.      sort(vs.begin(),vs.end());
     16.      for (vector<string>::iterator i = vs.begin();
     17.           i != vs.end(); ++i)   cout << *i << " ";
     18.      cout << endl;
     19.  }

którego uruchomienie powinno spowodować wypisanie na ekranie nazw czterech języków programowania w porządku alfabetycznym. Program jest celowo zbyt skomplikowany jak na proste zadanie, jakie wykonuje: chodzi tu raczej o to by sprawdzić, czy instalacja C++ jest prawidłowa.

Przy okazji podkreślmy, że

dla każdego projektu w C++ tworzymy odrębny katalog

o umiejętnie dobranej nazwie i przemyślanej lokalizacji w strukturze katalogów. Nieprzestrzeganie tego zalecenia wcześniej czy później (raczej wcześniej) doprowadzi do powstania chaosu niemożliwego do opanowania.


1.1.1 Linux

W najprostszej sytuacji są użytkownicy Linuksa: nie potrzebują bowiem niczego ponad to, co już prawdopodobnie mają, nawet jeśli nie byli tego świadomi. Należy tylko zadbać podczas instalacji samego systemu, aby zaznaczyć do instalacji pakiet „dla programistów” (jeśli tego nie zrobiliśmy, to można zainstalować go później jednym poleceniem za pomocą instalatora właściwego dla danej dystrybucji).

Jeśli w aktualnym katalogu mamy plik źródłowy zawierający program w C++, np. wspomniany wyżej plik testInst.cpp, to komenda

    g++ -o testInst testInst.cpp
powinna spowodować uruchomienie kompilatora i linkera (konsolidatora) i, jeśli nie zostały wykryte żadne błędy, pojawienie się na dysku, w tym samym katalogu, pliku testInst, który właśnie jest plikiem wykonywalnym. W świecie Linuxa pliki wykonywalne tradycyjnie nie mają żadnego rozszerzenia, choć oczywiście nic nie stoi na przeszkodzie, abyśmy takie rozszerzenie, np.  .exe, dodali: nazwa pliku wykonywalnego będzie taka, jaką podamy po opcji '-o' powyższej komendy. Jeśli opcję tę w ogóle pominiemy, to przyjęta zostanie domyślna nazwa a.out.

Jeśli w programie używamy nowych konstrukcji językowych (ze standardu 2014), może okazać się konieczne dodanie opcji '-std=c++14'; dobrze jest też dodać opcje które wymuszą sprawdzanie zgodności ze standardem – na przykład:

    g++ -o testInst -std=c++14 -pedantic-errors -Wall testInst.cpp
(w przypadku tego programu nie jest to konieczne). Program zawarty w pliku wykonywalnym uruchamiamy pisząc po prostu jego nazwę poprzedzoną znakami './', a więc w naszym przypadku './testInst', i wciskając klawisz Enter. Zatem przebieg takiej sesji mógłby być następujący:
    cpp> g++ -o testInst testInst.cpp
    cpp> ./testInst
    C++ Haskell Java Python

Jeśli nasz program zapisany jest w wielu plikach, to podajemy je wszystkie; można używać znaków uniwersalnych, czyli tzw. dżokerów (ang. wild cards), takich jak np. gwiazdki

    cpp> g++ -o testInst *.cpp
Plik wykonywalny powstaje, oczywiście, jeden. Dodatkowe informacje i opis wszystkich opcji kompilatora i linkera dostępne są, jak zwykle, na stronie pomocy man (komenda man g++) lub poprzez program info (info g++). W wielu edytorach można kompilację i uruchamianie programu przypisać do mnemoników klawiszowych; istnieją też graficzne programy bardzo ułatwiające pisanie programów w C++ (jak Eclipse, Anjuta, Geany, KDevelop, CodeWarrior, Code::Blocks — można je łatwo znaleźć w internecie). Większość dobrych edytorów tekstu zapewnia podkreślanie składni, zwijanie i rozwijanie struktur, automatyczne wcinanie i inne udogodnienia do redagowania plików źródłowych C/C++.


1.1.2 Windows


1.1.2.1 Visual C++ i Studio .NET

Dobry kompilator C++ wchodzi w skład pakietu Visual Studio firmy Microsoft. Jest on wyposażony w bogaty interfejs graficzny, funkcje pomocy, debugger itd. Istnieje wersja darmowa, Visual Studio Express, w zupełności wystarczająca do nauki programowania. Osobom posiadającym to narzędzie można tylko przypomnieć, aby zawsze przed przystąpieniem do pisania programu zadbali o utworzenie najpierw tzw. projektu, w osobnym katalogu, przeznaczonym tylko na pliki wchodzące w skład tego projektu. Tworząc nowy projekt zadbać trzeba o jego właściwy typ, w naszym przypadku będzie to 'Console Application' lub 'Managed C++ Empty Project'; zaniedbanie tego prowadzi do błędów kompilacji z raczej niewiele wyjaśniającymi komunikatami. Uruchamiać kompilator można zarówno korzystając z interfejsu graficznego jak i bezpośrednio z linii poleceń (wywołując program cl (co jest skrótem od compile and link). Kompilator ma wiele opcji, z których dobrze będzie wybrać '-Wall -Za -GR -EHsc', które, między innymi, włączą komunikaty o błędach, a za to wyłączą niestandardowe rozszerzenia języka.

T.R. Werner, 25 lutego 2017; 22:31