C/Używanie kompilatora

Z Wikibooks, biblioteki wolnych podręczników.
< C
Skocz do: nawigacja, szukaj

Język C jest językiem kompilowanym, co oznacza, że potrzebuje specjalnego programu - kompilatora - który tłumaczy kod źródłowy, pisany przez człowieka, na język rozkazów danego komputera. W skrócie działanie kompilatora sprowadza się do czytania tekstowego pliku z kodem programu, raportowania ewentualnych błędów i produkowania pliku wynikowego.

Kompilatory[edytuj]

Kompilator uruchamiamy  :

  • ze zintegrowanego środowiska programistycznego ( ang. IDE)
  • z konsoli (linii poleceń).

Przejść do konsoli można dla systemów :

  • typu UNIX w trybie graficznym użyć programów gnome-terminal, konsole albo xterm,
  • Windows "Wiersz polecenia" (można go znaleźć w menu Akcesoria albo uruchomić wpisując w Start -> Uruchom... "cmd").

GCC[edytuj]

Wikipedia, nasz siostrzany projekt, zawiera artykuł na temat GCC.

GCC (ang. GNU Compiler Collection)[1] jest to darmowy zestaw kompilatorów, m.in. języka C ( gcc) rozwijany w ramach projektu GNU. Dostępny jest on na dużą ilość platform sprzętowych, obsługiwanych przez takie systemy operacyjne jak: AIX, *BSD, Linux, Mac OS X, SunOS, Windows. Na niektórych systemach (np. Windows) nie jest on jednak dostępny automatycznie. Należy zainstalować odpowiednie narzędzia (poprzedni rozdział).

Wersja[edytuj]

gcc --version


Otrzymujemy ( przykładowy wynik ) :

gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


v[edytuj]

Użycie flagi v powoduje wydrukowanie na standardowym wyjściu błędu (ang. standard error output) komend uruchamianych w trakcie kompilacji oraz wersji programu kompilatora [2]

gcc -v

przykładowy wynik :

 Using built-in specs.
 COLLECT_GCC=gcc
 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
 Target: x86_64-linux-gnu
 Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.1-10ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9) 

Pomoc[edytuj]

man gcc

lub w postaci pliku tekstowego :[3]

man gcc | col -b > gcc.txt

Kompilacja[edytuj]

Aby skompilować kod języka C za pomocą kompilatora G++, napisany wcześniej w dowolnym edytorze tekstu, należy uruchomić program z odpowiednimi parametrami. Podstawowym parametrem, który jest wymagany, jest nazwa pliku zawierającego kod programu który chcemy skompilować.

gcc kod.c 
Rezultatem kompilacji będzie plik wykonywalny, z domyślną nazwą (w systemach Unix jest to "a.out").

Jest to metoda niezalecana, ponieważ w przypadku, gdy skompilujemy w jednym katalogu kilka plików z kodem, kolejne pliki wykonywalne zostaną nadpisane i w rezultacie otrzymamy tylko jeden (ostatni) skompilowany kod. Aby wymusić na G++ nazwę pliku wykonywalnego musimy skorzystać z parametru "-o <nazwa>":

gcc -o program kod.c
W rezultacie otrzymujemy plik wykonywalny o nazwie program.

Pracując nad złożonym programem składającym się z kilku plików źródłowych (.c), możemy skompilować je niezależnie od siebie, tworząc tak zwane pliki typu obiekt, z rozszerzeniem .o (ang. Object File). Następnie możemy stworzyć z nich jednolity program w procesie konsolidacji (linkowaniu). Jest to bardzo wygodne i praktyczne rozwiązanie ze względu na to, iż nie jesteśmy zmuszeni kompilować wszystkich plików tworzących program za każdym razem na nowo, a jedynie te, w których wprowadziliśmy zmiany Aby skompilować plik bez linkowania używamy parametru "-c <plik>":

gcc -o program1.o -c kod1.c
gcc -o program2.o -c kod2.c

Otrzymujemy w ten sposób pliki typu obiekt program1.o i program2.o. A następnie tworzymy z nich program główny:

gcc -o program program1.o program2.o

Możemy użyć również flag, m.in. aby włączyć dokładne, rygorystyczne sprawdzanie napisanego kodu (co może być przydatne, jeśli chcemy dążyć do perfekcji), używamy przełączników:

gcc kod.c -o program -Werror -Wall -W -pedantic -ansi

Więcej informacji na temat parametrów i działania kompilatora G++ można znaleźć na:

Borland[edytuj]

Zobacz podręcznik Borland C++ Compiler.

Błędy kompilacji[edytuj]

Jedną z najbardziej podstawowych umiejętności, które musi posiąść początkujący programista jest umiejętność rozumienia komunikatów o różnego rodzaju błędach, które sygnalizuje kompilator. Wszystkie te informacje pomogą Ci szybko wychwycić ewentualne błędy (których na początku zawsze jest bardzo dużo). Nie martw się, że na początku dość często będziesz oglądał wydruki błędów, zasygnalizowanych przez kompilator - nawet zaawansowanym programistom się to zdarza. Kompilator ma za zadanie pomóc Ci w szybkiej poprawie ewentualnych błędów, dlatego też umiejętność analizy komunikatów o błędach jest tak ważna.

Zaczynamy analizę od pierwszego komunikatu kompilatora. Poprawiamy błąd i ponownie kompilujemy (może wtedy znikną pozostałe błędy).

GCC[edytuj]

Komunikaty[edytuj]

Język komunikatów zależy od zmiennych środowiska, np. :[4]

  • LANG
  • LC_CTYPE
  • LC_MESSAGES
  • LC_ALL


echo $LANG
pl_PL.UTF-8

Błędy składniowe[edytuj]

Kompilator jest w stanie wychwycić błędy składniowe, które z pewnością będziesz popełniał. Kompilator GCC wyświetla je w następującej formie:

 nazwa_pliku.c:numer_linijki:opis błędu

Kompilator dość często podaje także nazwę funkcji, w której wystąpił błąd.


Przykładowo, błąd deklaracji zmiennej w pliku test.c:

#include <stdio.h>
 
int main ()
{
 intr r;
 printf ("%d\n", r);
}

Spowoduje wygenerowanie następującego komunikatu o błędzie:

test.c: In function ‘main’:
test.c:5: error: ‘intr’ undeclared (first use in this function)
test.c:5: error: (Each undeclared identifier is reported only once
test.c:5: error: for each function it appears in.)
test.c:5: error: syntax error before ‘r’
test.c:6: error: ‘r’ undeclared (first use in this function)

Co widzimy w raporcie o błędach?

W linii 5 użyliśmy nieznanego (undeclared) identyfikatora intr - kompilator mówi, że nie zna tego identyfikatora, jest to pierwsze użycie w danej funkcji i że więcej nie ostrzeże o użyciu tego identyfikatora w tej funkcji. Ponieważ intr nie został rozpoznany jako żaden znany typ, linijka intr r; nie została rozpoznana jako deklaracja zmiennej i kompilator zgłasza błąd składniowy (syntax error). W konsekwencji r nie zostało rozpoznane jako zmienna i kompilator zgłosi to jeszcze w następnej linijce, gdzie używamy r.


error: initializer element is not constant

Ten błąd powstaje gdy:

  • za pomocą jednej instrukcji deklarujemy i inicjujemy zmienną
  • do nadania wartości używamy wyrażenia a nie za stałej wartości (liczba)

Rozwiązaniem jest rozdzielenie deklaracji i inicjalizacji na 2 instrukcje.

Ostrzeżenie : niejawna deklaracja funkcji, np :

t.c:696:17: warning: implicit declaration of function ‘dDrawLine’

powstanie gdy :

  • nie dołączymy odpowiedniej biblioteki zawierającej deklarację funkcji,
  • deklaracja własnej funkcji będzie zawarta w programie ale nie zostanie rozpoznana z powodu błędów składniowych

Błędy związane z bibliotekami[edytuj]

Przykładowy komunikat:

/usr/bin/ld: cannot find -lXmu

Problem jest związany z opcją oznaczoną literą l linkera ( ld) :[5]

-llibrary

Linker nie może znaleźć biblioteki liblibrary, czyli w tym przypadku libXmu.

Sprawdzamy czy mamy taką biblioteką zainstalowaną, jeśli nie to szukamy pakietu libXmu np. w menadżerze pakietów Synaptic (w Ubuntu libXmu-dev) i instalujemy go.


Inny podobny komunikat dotyczący biblioteki matematycznej : [6]

undefined reference to 'pow' collect2: error: ld returned 1 exit status

Może być spowdowany kolejnością linkowania bibliotek, np w pliku MAKFILE, dobra kolejność :

LIBS =  -lcairo -lmpfr -lm 

zła :

LIBS =  -lm -lcairo -lmpfr

Inne błędy[edytuj]

r1.c:194:3: error: stray ‘\342’ in program
r1.c:194:3: error: stray ‘\210’ in program
r1.c:194:3: error: stray ‘\222’ in program

Błąd ten jest spowodowany występowaniem w kodzie innych znaków niż ASCI.[7] Prawdopodobnie skopiowano znaki z innego programu , np. :

  • pliku pdf
  • pliku/programu Microsoft Word
  • kalkulatora gcalctool

Rozwiązanie :

  • usuń skopiowany tekst
  • wpisz go ręcznie

Zobacz również[edytuj]

Źródła[edytuj]

  1. GCC (ang. GNU Compiler Collection)
  2. Opcje gcc
  3. GCC and Make by Chua Hock-Chuan
  4. 3.19 Environment Variables Affecting GCC
  5. Dokumentacja Gcc : 3.13 Options for Linking
  6. [ http://stackoverflow.com/questions/12824134/undefined-reference-to-pow-in-c-despite-including-math-h Undefined reference to pow( ) in C, despite including math.h ]
  7. gcc: error: stray ‘\342’ in program - www.giannistsakiris.com