Witam i witam ponownie.
W tym wykładzie chcę tylko omówić kilka typowych kompilatorów i ostrzeżeń.
Rozmawialiśmy o niektórych typowych problemach c.
Ale czasami nawet nie wiesz, że masz te błędy w swoim programie, gdy
kompilator próbuje ci to powiedzieć.
Błędy i ostrzeżenia kompilatora wydają się być naprawdę tajemnicze dla nowych programistów.
Mogą ci mówić, że brakuje ci średnika, ale oznacza nieosiągalny koniec instrukcji.
A dla kogoś nowego mogą nawet nie wiedzieć, co to oznacza.
Dlatego pisanie dużej ilości kodu i rozszyfrowanie
niektórych z tych ostrzeżeń kompilatora wymaga sporej praktyki.
Ale przed tym chciałbym cię uprzedzić.
Tak więc niektóre z typowych problemów, które widzieliście w
poprzednim wykładzie, opiszę niektóre ostrzeżenia i błędy kompilatora oraz to, co faktycznie powie.
Bardzo, bardzo ważne jest, aby powiedzieć ci, abyś zrozumiał, co mówi ci kompilator.
Jeśli kompilator mówi ci o błędach, ale nie rozumiesz tego błędu,
naprawienie tego kodu zajmie ci znacznie więcej czasu.
Ale jeśli widzisz błąd i wiesz dokładnie, co mówi,
możesz natychmiast go naprawić.
Pamiętam, że byłem w laboratorium, kiedy zaczynałem
programować, i brakowałoby mi
średnika, co jest bardzo powszechne. A kompilator powiedziałby mi, że brakuje mi średnika,
ale nie wiedziałbym tego,
powiedziałby po prostu nieosiągalny koniec instrukcji, a ja zapytałbym, co to
znaczy, co to jest instrukcja. Byłbym bardzo zdezorientowany.
Dlatego właśnie chciałem dać ci kilka wskazówek, co kompilator tak naprawdę próbuje ci powiedzieć.
Dlatego bardzo trudno jest zrozumieć, na co narzeka kompilator.
Odszyfrowanie tych wiadomości jest
czasami bardzo mylące.
Musisz więc zrozumieć te błędy kompilatora, aby je naprawić, całkiem proste.
Kompilator wykonuje za Ciebie połowę pracy.
Sprawdza składnię, mówiąc dokładnie, co jest nie tak, więc
powinieneś wykorzystać to na swoją korzyść.
Ale czasami trudno jest dokładnie zrozumieć, co mówi, zwłaszcza jeśli jesteś
nowy i nie rozumiesz części terminologii.
Kompilator podejmuje decyzje o tym, jak przetłumaczyć Twój kod,
którego programista nie napisał w kodzie.
Jest to wygodne dla programu i kompilatora, dzięki czemu
można go napisać bardziej zwięźle.
Z tej funkcji korzystają tylko doświadczeni programiści.
Więc mówię ci, kiedy kompilujesz, zawsze powinieneś
używać opcji dash wall.
To wszystko włączy.
Czasami bardziej zaawansowana funkcja polega na tym,
że faktycznie wyjmiesz
trochę rzeczy, tłumaczenie będzie trochę bardziej wydajne.
Ale kiedy to dodasz,
spowodujesz, że program zostanie skompilowany w inny sposób.
W rezultacie możesz mieć w swoim kodzie ostrzeżenia, o których nie wiesz.
Powodem, dla którego ci mówię, jest to, że zawsze chcesz kompilować z określoną opcją,
którą jest opcja tablicy rozdzielczej.
I faktycznie domyślnie jest to włączone w blokach kodu.
A to powiadomi Cię o wszystkich przypadkach, w których kompilator
robi rzeczy, o których nie wiesz.
Włącza również wszystkie ostrzeżenia, daje
dużo informacji, jest to bardzo przydatna opcja kompilatora.
Kiedy już włączysz tę opcję, możesz
spróbować pomóc ci lepiej zrozumieć, co mówi ci kompilator.
Kompilator pokaże więc dwa
rodzaje problemów. Jeden to błąd.
To faktycznie uniemożliwi utworzenie programu.
Wystąpił błąd składniowy i nie można skompilować programu.
Żadna praca wykonywalna
nie została odtworzona i. Zwykle, gdy widzisz błędy kompilatora, zawsze chcesz
skupić się na tym pierwszym błędzie.
To najbardziej niezawodny błąd,
ponieważ niektóre inne błędy mogą wynikać z tego pierwszego błędu.
Dlatego zawsze skupiaj się na tym pierwszym błędzie. Najpierw napraw błędy u góry,
a następnie skompiluj ponownie i zobacz, czy inne błędy zniknęły.
Ostrzeżenia. Ostrzeżenia to komunikaty, które
kompilator wyświetla w specjalnych sytuacjach, w których wykryto pewien typ anomalii.
Nie są to błędy krytyczne. Więc plik wykonywalny zostanie utworzony.
Ale nadal jest to coś, co powinieneś naprawić.
Ostrzeżenie jest z jakiegoś powodu. Albo robisz coś nieprawidłowo,
albo może to spowodować problem w przyszłości.
Dlatego chcesz zawsze naprawiać wszystkie ostrzeżenia.
Kompilując z opcją tablicy rozdzielczej, nie uważa
się, że program jest poprawny, dopóki wszystkie ostrzeżenia nie zostaną wyeliminowane.
Więc kompilacja nie zawiedzie. Dlatego radzę ci
używać tej opcji, a także widzieć wszystko, co dzieje się w kompilatorze.
Tak więc niektóre z najczęstszych komunikatów kompilatora, które napotkasz, będą
bezpośrednio związane z niektórymi z najczęstszych problemów c, o
których wspominaliśmy wcześniej.
Jeśli zmienna jest niezadeklarowana, zobaczysz tę zmienną komunikatu jako niezadeklarowaną za
pomocą tej funkcji.
Jest to jeden z najczęstszych i zwykle łatwiejszy do wykrycia.
Następnie wyświetli również symbol przed
tym komunikatem.
Zasadniczo powie, że
próbujesz użyć tej zmiennej, ale nigdy jej nie zadeklarowałeś.
Wiemy, że deklarując zmienną, określasz typ danych.
Nie możesz po prostu podpisywać danych do zmiennych, które nie istnieją.
Niejawna deklaracja ostrzegawcza funkcji, jest to związane z deklaracjami funkcji.
Dzieje się tak, gdy próbujesz wywołać funkcję, ale jeśli
funkcja nie ma skojarzonej z nią implementacji. Nie dodałeś nagłówka lub nie
zadeklarowałeś go. Więc nie wie, gdzie to jest
i nie wie, w jaki sposób funkcja jest zadeklarowana, nie zna argumentów, nie zna wartości zwracanej.
Nie ma informacji o samej funkcji?
Aby rozwiązać ten problem, zawsze deklaruj prototyp funkcji na górze.
Kolejne ostrzeżenie, które powie, że kontrola ostrzeżenia osiągnie koniec funkcji nieważnej, stanie
się tak, gdy funkcja została zdefiniowana jako zwracająca wynik, który jest nieważny, ale
nie ma instrukcji return zawartej w funkcji.
Więc zapomniałeś zwrócić danych.
Albo funkcja jest niepoprawnie zdefiniowana, gdy trzeba usunąć typ
danych przed deklaracją funkcji, albo zapomniałeś dodać
tę instrukcję return. Aby naprawić to
ostrzeżenie, należy zmienić jeden z pozostałych.
Ale widzisz, jak to jest ostrzeżenie. Nadal możesz tam skompilować, ale
człowiek, który może naprawdę spowodować problemy z cięciem w twoim programie.
Jeśli spodziewasz się, że funkcja zwróci coś, a tak nie jest, więc chcesz
naprawić nieużywaną zmienną ostrzeżeń, kolejne powszechne ostrzeżenie.
Jest to drukowane przez kompilator, gdy deklarowana jest zmienna, ale nigdy nie jest używana.
Nie powinieneś deklarować zmiennej, jeśli jej nie
używasz, więc usuń tę deklarację.
Zwykle dostaję je dość często, kiedy robię niektóre z moich demonstracji,
ponieważ zostawiam zmienne, których nigdy nie używam.
Lub kiedy demonstrowałem, jak zadeklarować zmienną, a potem
skompilowałem ją, aby pokazać, że skompilowana, otrzymywałem ostrzeżenie, że nigdy nie była używana.
Więc to jest w porządku, ponieważ coś demonstrowałem. Ale usuń
zmienne, jeśli nie są używane. Nie ma potrzeby deklarowania.
Niezdefiniowane odniesienie do. Dzieje się to w fazie łączenia.
Więc pamiętaj o kompilatorze lub fazie kompilacji, to się skompiluje.
Najpierw uruchomi preprocesor, następnie wygeneruje pliki obiektowe, a następnie weźmie te pliki obiektowe
i połączy je razem, aby utworzyć kompletny program.
Dlatego w fazie
łączenia musi rozwiązać wszelkie zależności zewnętrzne.
A konkretnie wszelkie funkcje, które wywołujesz, muszą
zostać gdzieś zaimplementowane.
Więc jeśli nie ma tego pliku obiektowego, spowoduje to ten problem.
Próbujesz wywołać funkcję, ale nie mamy do niej kodu.
Musisz więc albo upewnić się, że łączysz się
z tym plikiem.
Zwykle link pojawi się
za Ciebie, ale w GCC możesz po prostu użyć opcji myślnika
l, aby dodać plik z linkami. Więc jeśli używasz funkcji w pliku
nagłówkowym matematyki, ale nie tworzysz linku do pliku obiektu matematycznego, otrzymasz ten błąd.
Dzieje się tak również, jeśli masz zdefiniowany przez użytkownika i
nie dołączyłeś pliku źródłowego c.
Masz więc wiele plików źródłowych c.
Jeden z plików źródłowych c implementuje tę funkcję.
Inny plik źródłowy c zawiera nagłówek i
wywołuje go, ale
nigdy nie skompilowałeś innego pliku źródłowego c, który ma implementację, zobaczysz
ten błąd.
Więc upewnij się, że przynosisz ten plik źródłowy, upewnij się,
że przynosisz wszystkie pliki źródłowe biblioteki standardowej, jeśli zwykle potrzebujesz tego wyraźnie, nie musisz tego robić.
Innym częstym błędem jest konflikt typów dla.
Dzieje się tak, gdy faktycznie zdefiniowałeś lub zadeklarowałeś prototyp funkcji, a kiedy zacząłeś
go implementować, nie było to to samo, co deklarujesz.
Na przykład prototyp ma typ wyniku i nazwę nawiasów dla parametrów,
a następnie średnik.
A kiedy definiujesz implementację,
masz inny rzeczywisty nagłówek funkcji.
Masz inny typ zwrotu lub inną liczbę parametrów.
A to mówi dobrze, hej, masz
tę jedną deklarację funkcji. A kiedy przejdziesz do implementacji poniżej, jest zupełnie inaczej.
Więc jest niezgodność.
I to faktycznie pokaże ci na linii, że konflikt pojawia się
w poprzedniej definicji, który spowodował sprzeczność.
Tak więc w implementacji zwykle pokazuje ci linię, ponieważ
zwykle deklarujesz swoje funkcje na górze.
Błędy w czasie wykonywania. Błędy uruchomieniowe to problemy w
kodzie, które występują podczas uruchamiania programu, a nie podczas jego kompilacji.
Więc są to
zwykle awarie lub błędy niekrytyczne, w których tablica
jest poza granicami lub coś w tym rodzaju.
Kiedy program jest uruchomiony, pojawia się jakiś błąd logiczny.
Dlatego wykonywanie programów w języku C może nagle zakończyć się awarią, gdy zostanie wykryty błąd w czasie
wykonywania, coś, z czym nie może sobie poradzić. Występuje uszkodzenie pamięci, jak
wspomniałem.
Błędy poza zakresem zwykle powodują awarie programów.
Zwykle zobaczysz błąd segmentacji.
A błąd segmentacji tak naprawdę nic ci nie mówi.
Więc zazwyczaj to, co chcesz zrobić, aby dalej zdiagnozować ten
problem, to spojrzeć na stos wywołań,
jak wspomniałem wcześniej, program wywala się krok po
kroku, aby zobaczyć, która linia powoduje awarię.
Możesz pobrać stos wywołań, jeśli istnieje plik podstawowy, o którym wspomniałem wcześniej.
Następnie ze stosu wywołań można zobaczyć, która linia ulega awarii.
Albo jeszcze lepiej, uruchom debugger, krok po linii, a kiedy wykonasz wiersz, debugger,
zobaczysz awarię programu i możesz go zidentyfikować w ten sposób.
To jest jeszcze raz więcej wskazówek
dotyczących błędów kompilatora, ostrzeżeń i komunikatów oraz ich interpretacji.
W rzeczywistości są
linki w Internecie. Lub jeśli
skorzystasz z Google, poinformuje Cię o każdym błędzie kompilatora
i ostrzeżeniu, które można wygenerować, i faktycznie poda
definicję, dlaczego to zostało utworzone, i na
czym zasadniczo polega problem.
Ponownie, te błędy kompilacji mogą być bardzo tajemnicze.
I nawet jedno słowo mówiło o
nieosiągalnej kontroli. Wiesz z tego opisu koniecznie,
jeśli nie miałeś tego doświadczenia, to znaczy, och, nigdy nie zwracasz czegoś z funkcji.
Ale jeśli tak, to jeden z najlepszych sposobów na znalezienie
i naprawienie problemów w programie, gdy masz błędy kompilatora i nie rozumiesz
tego kompilatora, wygoogluj go. I zazwyczaj to, co się stanie, to przepełnienie stosu.
I powie ci, hej, to jest twój błąd, tak możesz
go rozwiązać. Robię to do dziś.
Programuję w języku c od 15 lat, ale wciąż są
chwile, kiedy napotykam różne rzeczy i zastanawiam się, co to dokładnie oznacza.
Wygoogluję to, wezmę kompilator, umieszczę w cudzysłowie i powie mi
dokładnie, co się dzieje.
Przepełnienie stosu to naprawdę dobra strona internetowa.
I może naprawdę zaoszczędzić dużo czasu
w procesie debugowania. Nie próbuj zgadywać, kiedy widzisz kompilatory lub ostrzeżenia.
Ten kompilator próbuje ci coś powiedzieć i dokładnie określi, co się dzieje.
Więc jeśli to zrozumiesz, będziesz w stanie rozwiązać swój problem znacznie, znacznie szybciej.
A jeśli nie jest to coś, co
znasz, przejdź do przepełnienia stosu lub przejdź do strony internetowej, która opisuje je wszystkie
i możesz to rozszyfrować w ten sposób.
Mam nadzieję, że to było pomocne. Dziękuję Ci.