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 (w wypadku platformy .NET wygląda to nieco inaczej). 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 plików źródłowych 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 połą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{"Python", "Haskell",
     13.                        "C++",    "Java"};
     14.      sort(vs.begin(),vs.end());
     15.      for (const auto& e : vs) cout << e << " ";
     16.      cout << endl;
     17.  }

którego uruchomienie powinno spowodować wypisanie na ekranie nazw czterech języków programowania w porządku alfabetycznym. Program może na razie być niezrozumiały, ale chodzi tu raczej o to by sprawdzić, czy Twoja instalacja C++ (kompilator, linker, biblioteki) jest prawidłowa. Spróbuj zapisać ten program w oddzielnym katalogu, skompilować go i uruchomić.

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 (dotyczy to również komputerów Mac).

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 standardów 2011/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
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 -pedantic-errors -Wall 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' a potem 'Empty project'; inaczej mogą pojawić się niewiele wyjaśniające komunikaty o błędach podczas kompilacji. 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, 23 lutego 2019; 23:59