Po co włączać ostrzeżenia?
C i C ++ kompilatory są notorycznie źle raportowania jakieś błędy powszechne programista domyślnie , takich jak:
- zapominając o inicjalizacji zmiennej
- zapominanie
return
o wartości z funkcji
- argumenty
printf
i scanf
rodzin nie spełniających ciąg formatu
- funkcja jest używana bez wcześniejszego zadeklarowania (tylko C)
Można je wykryć i zgłosić, ale zwykle nie są domyślnie; tej funkcji należy jawnie zażądać za pomocą opcji kompilatora.
Jak włączyć ostrzeżenia?
To zależy od twojego kompilatora.
Microsoft C i kompilatory C ++ zrozumieć jak przełączniki /W1
, /W2
, /W3
, /W4
i /Wall
. Użyj przynajmniej /W3
. /W4
i /Wall
może emitować fałszywe ostrzeżenia dla plików nagłówków systemowych, ale jeśli twój projekt kompiluje się czysto z jedną z tych opcji, idź do niego. Te opcje wykluczają się wzajemnie.
Większość innych kompilatory zrozumieć opcje takie jak -Wall
, -Wpedantic
i -Wextra
. -Wall
jest niezbędna, a cała reszta jest zalecana (pamiętaj, że pomimo nazwy -Wall
włącza tylko najważniejsze ostrzeżenia, a nie wszystkie ). Te opcje mogą być używane osobno lub wszystkie razem.
Twoje IDE może mieć sposób na włączenie ich z interfejsu użytkownika.
Po co traktować ostrzeżenia jako błędy? To tylko ostrzeżenia!
Ostrzeżenie kompilatora sygnalizuje potencjalnie poważny problem w kodzie. Wyżej wymienione problemy są prawie zawsze śmiertelne; inni mogą, ale nie muszą, ale chcesz, aby kompilacja nie powiodła się, nawet jeśli okaże się fałszywym alarmem. Zbadaj każde ostrzeżenie, znajdź pierwotną przyczynę i napraw ją. W przypadku fałszywego alarmu obejdź go - to znaczy użyj funkcji lub konstrukcji w innym języku, aby ostrzeżenie nie było już wyzwalane. Jeśli okaże się to bardzo trudne, wyłącz to ostrzeżenie indywidualnie dla każdego przypadku.
Nie chcesz po prostu pozostawiać ostrzeżeń jako ostrzeżeń, nawet jeśli wszystkie są fałszywymi alarmami. Może być OK w przypadku bardzo małych projektów, w których łączna liczba emitowanych ostrzeżeń jest mniejsza niż 7. W każdym razie i nowe ostrzeżenie łatwo zgubić się w zalewie starych znajomych. Nie pozwól na to. Po prostu spraw, aby cały projekt kompilował się czysto.
Uwaga: dotyczy to rozwoju programu. Jeśli wypuszczasz swój projekt na cały świat w formie źródłowej, dobrym pomysłem może być nie dostarczanie -Werror
lub równoważne w wydanym skrypcie kompilacji. Ludzie mogą próbować zbudować projekt przy użyciu innej wersji kompilatora lub innego kompilatora, który może mieć włączony inny zestaw ostrzeżeń. Możesz chcieć, aby ich kompilacja się powiodła. Nadal dobrym pomysłem jest włączenie ostrzeżeń, aby osoby, które widzą komunikaty ostrzegawcze, mogły wysyłać raporty o błędach lub łatki.
Jak traktować ostrzeżenia jako błędy?
To samo dzieje się z przełącznikami kompilatora. /WX
jest dla Microsoft, większość używa -Werror
. W obu przypadkach kompilacja zakończy się niepowodzeniem, jeśli zostaną wygenerowane jakiekolwiek ostrzeżenia.
C jest, jak wiadomo, językiem raczej niskiego poziomu, jak HLL. C ++, choć może wydawać się językiem znacznie wyższego poziomu niż C, nadal ma wiele cech. Jedną z tych cech jest to, że języki zostały zaprojektowane przez programistów dla programistów - a konkretnie programistów, którzy wiedzieli, co robią.
[Do końca tej odpowiedzi skupię się na C. Większość tego, co powiem, dotyczy również C ++, choć może nie tak mocno. Chociaż, jak słynie Bjarne Stroustrup, „C ułatwia strzelanie sobie w stopę; C ++ utrudnia, ale kiedy to robisz, zdmuchuje całą nogę”. ]
Jeśli wiesz, co robisz - naprawdę wiesz, co robisz - czasem może być konieczne „złamanie zasad”. Ale przez większość czasu większość z nas zgadza się, że dobre intencje chronią nas przed kłopotami i że bezmyślne łamanie tych zasad przez cały czas jest złym pomysłem.
Ale w C i C ++ istnieje zaskakująco duża liczba rzeczy, które możesz zrobić, które są „złymi pomysłami”, ale które nie są formalnie „niezgodne z regułami”. Czasami są czasem złym pomysłem (ale czasem można je obronić); czasami są to zły pomysł praktycznie przez cały czas. Ale tradycją zawsze nie było ostrzeganie o tych rzeczach - ponieważ ponownie założono, że programiści wiedzą, co robią, nie robiliby tych rzeczy bez dobrego powodu, byliby zirytowani przez grupę niepotrzebnych ostrzeżeń.
Ale oczywiście nie wszyscy programiści naprawdę wiedzą, co robią. W szczególności każdy programista C (bez względu na to, jak doświadczony) przechodzi fazę bycia początkującym programistą C. Nawet doświadczeni programiści C mogą być nieostrożni i popełniać błędy.
Wreszcie, doświadczenie pokazało nie tylko, że programiści popełniają błędy, ale że błędy te mogą mieć realne, poważne konsekwencje. Jeśli popełnisz błąd, a kompilator nie ostrzeże Cię o tym, a w jakiś sposób program nie zawiesi się natychmiast lub nie zrobi z tego powodu czegoś oczywistego niewłaściwego, błąd może czaić się tam, ukryty, czasami przez lata, dopóki nie spowoduje naprawdę duży problem.
Okazuje się więc, że w większości przypadków ostrzeżenia są dobrym pomysłem. Nawet doświadczeni programiści nauczyli się (tak naprawdę „ szczególnie doświadczeni programiści nauczyli się”), że w sumie ostrzeżenia przynoszą więcej korzyści niż szkody. Za każdym razem, gdy celowo zrobiłeś coś złego, a ostrzeżenie było uciążliwe, prawdopodobnie co najmniej dziesięć razy zrobiłeś coś nie tak przez przypadek, a ostrzeżenie uratowało cię od dalszych kłopotów. I większość ostrzeżeń można wyłączyć lub obejść kilka razy, gdy naprawdę chcesz zrobić coś „złego”.
(Klasycznym przykładem takiego „błędu” jest test
if(a = b)
. Przez większość czasu jest to błąd, więc większość kompilatorów obecnie ostrzega przed nim - niektóre nawet domyślnie. Ale jeśli naprawdę chcesz zarówno przypisaćb
do niego, jaka
i przetestować w rezultacie możesz wyłączyć ostrzeżenie, piszącif((a = b))
.)Drugie pytanie brzmi: dlaczego chcesz poprosić kompilator o traktowanie ostrzeżeń jako błędów? Powiedziałbym, że to z powodu ludzkiej natury, a szczególnie zbyt łatwej reakcji powiedzenia „Och, to tylko ostrzeżenie, to nie jest tak ważne, posprzątam to później”. Ale jeśli jesteś prokrastynatorem (a ja nie wiem o tobie, ale jestem okropnym prokrastynatorem), łatwo jest odłożyć niekoniecznie porządki w zasadzie na zawsze - a jeśli masz zwyczaj ignorowania ostrzeżeń, coraz łatwiej przeoczyć ważny komunikat ostrzegawczy, który siedzi tam, niezauważony, pośród wszystkich, które ignorujesz.
Poproszenie kompilatora, aby traktował ostrzeżenia jako błędy, jest małą sztuczką, w którą możesz się zagrać, aby obejść ten ludzki pomysł.
Osobiście nie nalegam na traktowanie ostrzeżeń jak błędów. (W rzeczywistości, jeśli mam być szczery, mogę powiedzieć, że praktycznie nigdy nie włączam tej opcji w moim „osobistym” programowaniu). Ale możesz być pewien, że mam włączoną tę opcję w pracy, gdzie nasz przewodnik po stylu (który ja napisał) nakazuje jego użycie. I powiedziałbym - podejrzewam, że powiedziałby większość profesjonalnych programistów - że każdy sklep, który nie traktuje ostrzeżeń jako błędów w C, zachowuje się nieodpowiedzialnie, nie przestrzega powszechnie przyjętych najlepszych praktyk branżowych.
źródło
if(a = b)
, dlatego nie musimy o tym ostrzegać”. (Następnie ktoś tworzy listę 10 krytycznych błędów w 10 wydanych produktach, które wynikają z tego konkretnego błędu.) „Dobra, żaden doświadczony programista C nigdy nie napisałby tego ...”if (returnCodeFromFoo = foo(bar))
i oznaczać to, aby przechwycić i przetestować kod w jednym miejscu (Załóżmy, że jedynym celemfoo
jest uzyskanie efektów ubocznych!) Fakt, że naprawdę naprawdę doświadczony programista może wiedzieć, że to nie jest dobry styl kodowania nie ma znaczenia;)if (returnCodeFromFoo = foo(bar))
, to umieszczają komentarz i wyłączają ostrzeżenie (tak, że gdy programista konserwacji spojrzy na to 4 lata później, zrozumie, że kod jest celowy. To powiedziawszy, pracowałem z kimś, kto w (w krainie Microsoft C ++) upierał się, że najlepszym rozwiązaniem jest połączenie / Wall z traktowaniem ostrzeżeń jako błędów. Nie jest (chyba że chcesz wprowadzić wiele komentarzy tłumiących)Ostrzeżenia składają się z najlepszych porad, które niektórzy z najbardziej wykwalifikowanych programistów C ++ mogą upiec w aplikacji. Warto je trzymać.
C ++, jako kompletny język Turinga, ma wiele przypadków, w których kompilator musi po prostu zaufać, że wiesz, co robisz. Istnieje jednak wiele przypadków, w których kompilator może zdać sobie sprawę, że prawdopodobnie nie zamierzałeś pisać tego, co napisałeś. Klasycznym przykładem są kody printf (), które nie pasują do argumentów, lub std :: strings przekazywane do printf (nie to, że mi się to kiedykolwiek przytrafia!). W takich przypadkach napisany kod nie jest błędem. Jest to poprawne wyrażenie C ++ z poprawną interpretacją dla kompilatora. Ale kompilator ma silne przeczucie, że po prostu przeoczyłeś coś, co jest łatwe do wykrycia przez nowoczesny kompilator. To są ostrzeżenia. Są to rzeczy oczywiste dla kompilatora, wykorzystujące wszystkie surowe reguły języka C ++, które mogą być przeoczone.
Wyłączenie ostrzeżeń lub zignorowanie ich jest jak zignorowanie bezpłatnych porad od osób bardziej wykwalifikowanych niż ty. Jest to lekcja huberi, która kończy się albo, gdy lecisz zbyt blisko słońca i skrzydła się stopią, lub wystąpi błąd uszkodzenia pamięci. Między nimi każdego dnia spadnę z nieba!
„Traktuj ostrzeżenia jako błędy” to ekstremalna wersja tej filozofii. Chodzi o to, że rozwiązujesz każde ostrzeżenie, które daje ci kompilator - słuchasz każdej darmowej porady i postępujesz zgodnie z nią. To, czy jest to dobry model rozwoju, zależy od zespołu i od jakiego produktu pracujesz. Takie ascetyczne podejście może mieć mnich. Dla niektórych działa świetnie. Dla innych tak nie jest.
W wielu moich aplikacjach nie traktujemy ostrzeżeń jako błędów. Robimy to, ponieważ te konkretne aplikacje muszą się kompilować na kilku platformach z kilkoma kompilatorami w różnym wieku. Czasami okazuje się, że naprawienie ostrzeżenia z jednej strony nie jest niemożliwe bez ostrzeżenia na innej platformie. Jesteśmy więc tylko ostrożni. Szanujemy ostrzeżenia, ale nie pochylamy się za nimi.
źródło
equals
/hashCode
), a który z nich jest zgłaszany, to problem z jakością implementacji.Obsługa ostrzeżeń nie tylko poprawia kod, ale także czyni cię lepszym programistą. Ostrzeżenia powiedzą ci o rzeczach, które dziś mogą ci się wydawać mało, ale pewnego dnia ten zły nawyk powróci i odgryzie ci głowę.
Użyj poprawnego typu, zwróć tę wartość, oceń tę zwracaną wartość. Poświęć trochę czasu i zastanów się: „Czy to naprawdę poprawny typ w tym kontekście?” „Czy muszę to zwrócić?” I biggie; „Czy ten kod będzie przenośny przez następne 10 lat?”
Nabierz nawyku pisania kodu ostrzegawczego.
źródło
Pozostałe odpowiedzi są doskonałe i nie chcę powtarzać tego, co powiedzieli.
Innym aspektem „dlaczego włączyć ostrzeżenia”, który nie został właściwie dotknięty, jest to, że ogromnie pomagają w utrzymaniu kodu. Kiedy piszesz program o znacznych rozmiarach, niemożliwe staje się trzymanie tego wszystkiego w głowie na raz. Zazwyczaj masz funkcję lub trzy, o których aktywnie piszesz i myślisz, i być może plik lub trzy na ekranie, do których możesz się odwoływać, ale większość programu istnieje gdzieś w tle i musisz mu zaufać kontynuuje pracę.
Włączanie ostrzeżeń i używanie ich tak energicznie, jak to tylko możliwe, pomaga ostrzec cię, jeśli coś, co zmienisz, powoduje kłopoty z powodu czegoś, czego nie widzisz.
Weźmy na przykład ostrzeżenie o klanie
-Wswitch-enum
. Powoduje to ostrzeżenie, jeśli użyjesz przełącznika na wyliczeniu i pominiesz jedną z możliwych wartości wyliczenia. Jest to coś, co mogłoby się wydawać mało prawdopodobnym błędem: prawdopodobnie przynajmniej spojrzałeś na listę wartości wyliczeniowych, pisząc instrukcję switch. Możesz nawet mieć IDE, które wygenerowało dla ciebie opcje przełączania, nie pozostawiając miejsca na ludzkie błędy.To ostrzeżenie naprawdę działa, gdy sześć miesięcy później dodajesz kolejny możliwy wpis do wyliczenia. Ponownie, jeśli myślisz o danym kodzie, prawdopodobnie nic ci nie będzie. Ale jeśli to wyliczenie jest używane do wielu różnych celów i jest jednym z tych, które wymagają dodatkowej opcji, bardzo łatwo zapomnieć o aktualizacji przełącznika w pliku, którego nie dotknąłeś przez 6 miesięcy.
Możesz myśleć o ostrzeżeniach w taki sam sposób, jak myślisz o zautomatyzowanych przypadkach testowych: pomagają ci upewnić się, że kod jest rozsądny i robi to, czego potrzebujesz, gdy go piszesz, ale pomagają jeszcze bardziej, aby się upewnić, że kod cały czas robisz to, czego potrzebujesz, kiedy to robisz. Różnica polega na tym, że przypadki testowe działają bardzo wąsko w stosunku do wymagań twojego kodu i musisz je napisać, podczas gdy ostrzeżenia działają zasadniczo zgodnie z rozsądnymi standardami dla prawie całego kodu i są bardzo hojnie dostarczane przez trumny, które tworzą kompilatory.
źródło
Niestosowane ostrzeżenia wcześniej czy później doprowadzą do błędów w kodzie .
Na przykład debugowanie błędu segmentacji wymaga od programisty wyśledzenia przyczyny (przyczyny) błędu, który zwykle znajduje się na wcześniejszym miejscu w kodzie niż w linii, która ostatecznie spowodowała błąd segmentacji.
To bardzo typowe, że przyczyną jest linia, dla której kompilator wydał ostrzeżenie, które zignorowałeś, a linia, która spowodowała błąd segmentacji, linia, która ostatecznie zgłosiła błąd.
Naprawienie ostrzeżenia prowadzi do rozwiązania problemu. Klasyk!
Demonstracja powyższego. Rozważ następujący kod:
który po skompilowaniu z flagą „Wextra” przekazaną do GCC daje:
który i tak mógłbym zignorować i wykonać kod. A potem byłbym świadkiem „wielkiej” usterki segmentacji, jak mawiał mój profesor epikurusa IP:
Aby debugować to w scenariuszu w świecie rzeczywistym, należy zacząć od linii, która powoduje błąd segmentacji i spróbować ustalić, co jest przyczyną tej przyczyny. Musieliby szukać tego, co się stało
i
istr
wewnątrz tej kolosalnej ilości kodu tam ...Aż pewnego dnia znaleźli się w sytuacji, w której odkrywają, że
idx
jest używany niezainicjowany, a zatem ma wartość śmieci, co powoduje indeksowanie łańcucha (drogi) poza jego granicami, co prowadzi do błędu segmentacji.Gdyby tylko nie zignorowali ostrzeżenia, natychmiast znaleźliby błąd!
źródło
str[idx]
” nie jest „Okej, gdzie sąstr
iidx
zdefiniowano?”idx
jest to wartość oczekiwana na teście (nie jest to mało prawdopodobne, jeśli oczekiwaną wartością jest 0) i faktycznie wskazuje na niektóre wrażliwe dane, które nigdy nie powinny być drukowane po wdrożeniu.Traktowanie ostrzeżeń jako błędów jest tylko środkiem do samodyscypliny: skompilowałeś program, aby przetestować tę błyszczącą nową funkcję, ale nie możesz tego zrobić, dopóki nie naprawisz niechlujnych części. Nie ma żadnych dodatkowych informacji
Werror
, po prostu bardzo wyraźnie określa priorytety:To naprawdę sposób myślenia jest ważny, a nie narzędzia. Dane diagnostyczne kompilatora to narzędzie. MISRA (dla wbudowanego C) to kolejne narzędzie. Nie ma znaczenia, którego używasz, ale prawdopodobnie ostrzeżenia kompilatora są najłatwiejszym dostępnym narzędziem (można ustawić tylko jedną flagę), a stosunek sygnału do szumu jest bardzo wysoki. Więc nie ma powodu, aby go nie używać.
Żadne narzędzie nie jest niezawodne. Jeśli piszesz
const float pi = 3.14;
, większość narzędzi nie powie ci, że zdefiniowałeś π ze złą precyzją, co może prowadzić do problemów na drodze. Większość narzędzi nie podnosi brwiif(tmp < 42)
, nawet jeśli powszechnie wiadomo, że podawanie zmiennych bez znaczenia i używanie magicznych liczb to sposób na katastrofę w dużych projektach. Musisz zrozumieć, że każdy napisany przez ciebie „szybki test” jest po prostu: testem i musisz go przygotować, zanim przejdziesz do innych zadań, a jednocześnie dostrzeżesz jego wady. Jeśli pozostawisz ten kod bez zmian, debugowanie, jeśli po upływie dwóch miesięcy dodanie nowych funkcji będzie znacznie trudniejsze.Gdy przejdziesz do właściwego sposobu myślenia, nie ma sensu z niego korzystać
Werror
. Posiadanie ostrzeżeń jako ostrzeżeń pozwoli Ci podjąć świadomą decyzję, czy nadal warto uruchomić sesję debugowania, którą właśnie miałeś rozpocząć, lub przerwać ją i najpierw naprawić ostrzeżenia.źródło
clippy
narzędzie do szorowania Rust będzie ostrzegać o stałej wartości „3.14”. To właściwie przykład w dokumentacji . Ale jak można się domyślić po nazwie,clippy
jest dumny z tego, że jest agresywnie pomocny.Jako ktoś, kto pracuje ze starszym osadzonym kodem C, włączenie ostrzeżeń kompilatora pomogło pokazać wiele słabości i obszarów do zbadania podczas proponowania poprawek. W gcc wykorzystując
-Wall
a-Wextra
nawet-Wshadow
stały się niezbędne. Nie zamierzam podejmować każdego zagrożenia, ale wymienię kilka wyskakujących okienek, które pomogły pokazać problemy z kodem.Zmienne są pozostawione
Można to łatwo wskazać na niedokończoną pracę i obszary, które mogą nie wykorzystywać wszystkich przekazywanych zmiennych, co może być problemem. Spójrzmy na prostą funkcję, która może to spowodować:
Kompilowanie tego bez opcji -Wall lub -Wextra nie zwraca żadnych problemów. -Wall powie ci, że
c
to nigdy nie jest używane:-Wextra powie ci również, że twój parametr b nic nie robi:
Globalne zacienianie
Ten nieco trudny i nie pojawił się, dopóki nie
-Wshadow
został użyty. Zmodyfikujmy powyższy przykład, aby dodać, ale zdarza się, że istnieje globalny o tej samej nazwie co lokalny, co powoduje wiele zamieszania przy próbie użycia obu.Po włączeniu opcji -Wshadow łatwo zauważyć ten problem.
Formatuj ciągi
Nie wymaga to żadnych dodatkowych flag w gcc, ale nadal było źródłem problemów w przeszłości. Prosta funkcja próbująca wydrukować dane, ale z błędem formatowania może wyglądać następująco:
Nie powoduje to wydrukowania łańcucha, ponieważ flaga formatowania jest niepoprawna, a gcc z radością powie ci, że prawdopodobnie nie tego chciałeś:
To tylko trzy z wielu rzeczy, które kompilator może dla ciebie dwukrotnie sprawdzić. Istnieje wiele innych, takich jak używanie niezainicjowanej zmiennej, na którą zwracali uwagę inni.
źródło
possible loss of precision
” i „comparison between signed and unsigned
”. Trudno mi zrozumieć, ilu „programistów” zignorowało je (w rzeczywistości nie jestem pewien, dlaczego nie są błędami)sizeof
jest niepodpisany, ale domyślny typ liczby całkowitej jest podpisany. Typsizeof
wyniku,,size_t
jest zwykle używany do wszystkiego związanego z rozmiarem typu, takiego jak np. Wyrównanie lub liczba elementów tablicy / kontenera, podczas gdy liczby całkowite są ogólnie przeznaczone do użycia jako „int
chyba że jest to wymagane inaczej”. Biorąc pod uwagę, ilu ludzi uczy się w ten sposóbint
iteracji po kontenerach (w porównaniuint
dosize_t
), popełnienie błędu zepsułoby z grubsza wszystko. ; PTo jest konkretna odpowiedź na C i dlaczego jest to o wiele ważniejsze dla C niż dla czegokolwiek innego.
Ten kod kompiluje się z ostrzeżeniem . Jakie są i powinny być błędy w prawie każdym innym języku na planecie (z wyjątkiem języka asemblera) są ostrzeżenia w C. Ostrzeżenia w C prawie zawsze są błędami w przebraniu. Ostrzeżenia należy naprawić, a nie ukryć.
Z
gcc
, robimy to jakgcc -Wall -Werror
.To był również powód wysokiej niechęci do korzystania z niektórych ostrzeżeń API niezabezpieczonych w MS. Większość osób programujących w C nauczyła się ciężko traktować ostrzeżenia jako błędy i pojawiły się te rzeczy, które po prostu nie były tego samego rodzaju i chciały nieprzenośnych poprawek.
źródło
OSTRZEŻENIA KOMPILERA JEST TWOIM PRZYJACIELEM (nie krzyczy, wielkie litery dla podkreślenia).
Pracuję na starszych systemach Fortran-77. Kompilator mówi mi cenne rzeczy: niedopasowanie typu danych argumentu w wywołaniu podprogramu, przy użyciu zmiennej lokalnej przed ustawieniem wartości w zmiennej, jeśli mam zmienną lub argument podprogramu, który nie jest używany. To prawie zawsze są błędy.
Unikanie długiego postu: Gdy mój kod kompiluje się czysto, 97% działa. Drugi facet, z którym pracuję, kompiluje się z wyłączonymi wszystkimi ostrzeżeniami, spędza godziny lub dni w debuggerze, a następnie prosi mnie o pomoc. Po prostu kompiluję jego kod z włączonymi ostrzeżeniami i mówię mu, co naprawić.
źródło
Zawsze należy włączać ostrzeżenia kompilatora, ponieważ kompilator często może powiedzieć ci, co jest nie tak z twoim kodem. Aby to zrobić, przekazujesz
-Wall -Wextra
do kompilatora.Zazwyczaj należy traktować ostrzeżenia jako błędy, ponieważ zwykle oznaczają one, że coś jest nie tak z twoim kodem. Często jednak bardzo łatwo jest zignorować te błędy. Dlatego traktowanie ich jako błędów spowoduje niepowodzenie kompilacji, więc nie można zignorować błędów. Aby traktować ostrzeżenia jako błędy, przejdź
-Werror
do kompilatora.źródło
Ostrzeżenia kompilatora w C ++ są bardzo przydatne z kilku powodów.
1 - Pozwala pokazać, gdzie możesz popełnić błąd, który może wpłynąć na końcowy wynik twoich operacji. Na przykład, jeśli nie zainicjowałeś zmiennej lub wstawiłeś „=” zamiast „==” (istnieją tylko przykłady)
2 - Pozwala również pokazać, gdzie twój kod nie jest zgodny ze standardem c ++. Jest to przydatne, ponieważ jeśli kod jest zgodny z rzeczywistym standardem, łatwo będzie na przykład przenieść kod na inny format płyty.
Ogólnie rzecz biorąc, ostrzeżenia są bardzo przydatne, aby pokazać, gdzie masz błędy w kodzie, które mogą wpłynąć na wynik algorytmu lub zapobiec błędom, gdy użytkownik będzie korzystał z twojego programu.
źródło
Ignorowanie ostrzeżeń oznacza pozostawienie niechlujnego kodu, który nie tylko może powodować problemy w przyszłości dla kogoś innego, ale także sprawi, że ważne wiadomości kompilowane będą mniej zauważane przez Ciebie. Im więcej danych wyjściowych kompilatora, tym mniej ktokolwiek zauważy lub przeszkadza. Im czystsze tym lepiej. Oznacza to również, że wiesz, co robisz. Ostrzeżenia są bardzo nieprofesjonalne, nieostrożne i ryzykowne.
źródło
Kiedyś pracowałem dla dużej firmy (Fortune 50), która produkowała elektroniczne urządzenia testujące.
Podstawowym produktem mojej grupy był program MFC, który z biegiem lat generował dosłownie setki ostrzeżeń. Które zostały zignorowane w prawie wszystkich przypadkach.
To cholerny koszmar, gdy pojawiają się błędy.
Po tym stanowisku miałem szczęście, że zostałem zatrudniony jako pierwszy programista w nowym startupie.
Zachęcałem do stosowania zasady „brak ostrzeżeń” dla wszystkich wersji, z poziomami ostrzeżeń kompilatora ustawionymi na dość głośny.
Naszą praktyką było używanie ostrzeżenia #pragma - push / disable / pop dla kodu, który deweloper był pewien, że jest w porządku, wraz z instrukcją dziennika na poziomie debugowania, na wszelki wypadek.
Ta praktyka działała dla nas dobrze.
źródło
#pragma warning
nie tylko tłumi ostrzeżenia, służy podwójnym celom szybkiego komunikowania innym programistom, że coś jest zamierzone i nieprzypadkowe, i działa jako tag wyszukiwania do szybkiego lokalizowania potencjalnie problematycznych obszarów, gdy coś się psuje, ale naprawianie błędów / ostrzeżeń nie napraw to.Ostrzeżenie to błąd, który czeka na wystąpienie. Musisz więc włączyć ostrzeżenia kompilatora i uporządkować kod, aby usunąć wszelkie ostrzeżenia.
źródło
Jest tylko jeden problem z traktowaniem ostrzeżeń jako błędów: kiedy używasz kodu pochodzącego z innych źródeł (np. Bibliotek micro $ ** t, projektów open source), nie wykonali poprawnie swojej pracy, a skompilowanie kodu generuje tony ostrzeżeń.
I zawsze napisać kod, więc nie generuje żadnych ostrzeżeń lub błędów, i oczyścić go aż kompiluje bez generowania hałasu obcych. Śmieci, z którymi muszę pracować, przerażają mnie i jestem zdumiony, gdy muszę zbudować duży projekt i oglądać strumień ostrzeżeń, w którym kompilacja powinna jedynie ogłaszać, które pliki przetwarzała.
Dokumentuję również swój kod, ponieważ wiem, że rzeczywisty koszt oprogramowania wiąże się głównie z konserwacją, a nie z jego początkowym napisaniem, ale to inna historia ...
źródło
-Wall
a ty korzystasz-Wall -Wextra
.Niektóre ostrzeżenia mogą oznaczać możliwy błąd semantyczny w kodzie lub możliwy UB. Np.
;
Poif()
, nieużywana zmienna, zmienna globalna maskowana lokalnie lub porównanie podpisanych i niepodpisanych. Wiele ostrzeżeń związanych jest z analizatorem kodu statycznego w kompilatorze lub z naruszeniami normy ISO wykrywanymi w czasie kompilacji, które „wymagają diagnostyki”. Chociaż takie przypadki mogą być zgodne z prawem w jednym konkretnym przypadku, w większości przypadków byłyby wynikiem problemów projektowych.Niektóre kompilatory, np. Gcc, mają opcję wiersza poleceń do aktywacji trybu „ostrzeżenia jako błędy”, jest to miłe, choć okrutne narzędzie do edukacji początkujących programistów.
źródło
Fakt, że kompilatory C ++ akceptują kod kompilacyjny, który w oczywisty sposób powoduje w ogóle nieokreślone zachowanie, jest główną wadą kompilatorów. Powodem, dla którego tego nie naprawiają, jest prawdopodobnie uszkodzenie niektórych kompilacji.
Większość ostrzeżeń powinna być krytycznymi błędami, które uniemożliwiają ukończenie kompilacji. Domyślne wyświetlanie błędów i kompilacja mimo wszystko są niepoprawne, a jeśli nie przesłonisz ich, aby traktować ostrzeżenia jako błędy i pozostawić niektóre ostrzeżenia, prawdopodobnie zakończy się awaria programu i wykonywanie losowych czynności.
źródło
int i; if (fun1()) i=2; if (fun2()) i=3; char s="abcde"[i];
Ten kod eksponatów zachowanie niezdefiniowane wtedy i tylko wtedy, gdy obafun1()
ifun2()
może powrócićfalse
na tym samym realizacji funkcji. Co może, ale nie musi, być prawdą, ale jak ma to powiedzieć kompilator?Zdecydowanie powinieneś włączyć ostrzeżenia kompilatora, ponieważ niektóre kompilatory źle zgłaszają niektóre typowe błędy programistyczne, w tym następujące:
-> inicjalizacja zmiennej zostaje zapomniana -> zwracana wartość z funkcji jest pomijana -> proste argumenty w rodzinach printf i scanf, które nie pasują do ciągu formatu, funkcja jest używana bez uprzedniego zadeklarowania, choć dzieje się tak tylko w c
Ponieważ funkcje te można wykryć i zgłosić, zazwyczaj nie są one domyślnie; więc tej funkcji należy jawnie zażądać za pomocą opcji kompilatora.
źródło
Uspokój się: nie musisz, nie jest to konieczne. -Wall i -Werror zostały zaprojektowane przez maniaków refaktoryzujących kod: zostały wymyślone przez programistów kompilatorów, aby uniknąć zepsucia istniejących kompilacji po aktualizacji kompilatora po stronie użytkownika . Ta funkcja to nic, ale wszystko o decyzji o przerwaniu lub nie, aby przerwać kompilację.
Korzystanie z niego, czy nie, zależy wyłącznie od twoich preferencji. Używam go cały czas, ponieważ pomaga mi to naprawić błędy.
źródło
-Wall and -Werror was designed by code-refactoring maniacs for themselves.
[potrzebne źródło]-Wall
a-Werror
jedynie pytanie, czy to dobry pomysł. Które z ostatniego zdania brzmi tak, jakbyś powiedział, że tak.