Ta odpowiedź i dodane do niej komentarze pokazują sposób na wyłączenie kilku ostrzeżeń kompilatora za pomocą #pragma
dyrektyw.
Dlaczego miałby to robić? Zazwyczaj ostrzeżenia są z jakiegoś powodu i zawsze uważałem, że są to dobre powody. Czy istnieje „ważny przypadek”, w którym należy wyłączyć ostrzeżenia? W tej chwili nie mogę wymyślić żadnego, ale może to tylko ja.
Odpowiedzi:
Miałem tylko jedną sytuację, w której wyłączyłem ostrzeżenie. Rozważam błędy ostrzeżeń, więc normalnie nie wypuszczałbym ostrzeżeń. Jednak podczas opracowywania interfejsu API u klientów napotkałem problem polegający na tym, że metoda, która była potrzebna w fazie migracji przez jedną aplikację i z której nie powinna korzystać żadna inna, musiała zostać zawarta w bibliotece.
Najlepszym sposobem, w jaki mogłem powiedzieć wszystkim użytkownikom interfejsu API, że nie powinni wywoływać tej metody, było oznaczenie jej jako przestarzałej. Oznaczało to jednak, że jeden poprawny przypadek użycia został oznaczony jako ostrzeżenie kompilacyjne.
Eric Lippert napisał kilka postów na temat ostrzeżeń, w których znajdziesz informacje o tym, jak zespół kompilatora myśli o ostrzeżeniach.
Wewnętrzne pola typów wewnętrznych
Niewykorzystane przy użyciu dyrektyw nie są oznaczone ostrzeżeniami
źródło
Oto kilka ostrzeżeń, w których dokumentacja podaje powody, dla których warto je wyłączyć:
Inne przykłady obejmują ostrzeżenia o stosowaniu zamortyzowanych metod, jeśli wiesz, że nadal chcesz korzystać ze starej metody lub masz prywatnych członków, którzy nigdy nie są czytani lokalnie, ale zamiast tego mają refleksję.
Z mojego doświadczenia wynika, że C # ma mniejszą potrzebę wyłączania ostrzeżeń niż inne języki, takie jak C ++. Wynika to głównie z tego, że, jak mówi Eric Lippert na swoim blogu , „próbują zastrzec ostrzeżenia tylko dla tych sytuacji, w których możemy z całą pewnością stwierdzić, że kod jest uszkodzony, wprowadzający w błąd lub bezużyteczny”.
źródło
Przykład w C, z którym regularnie spotykam się z wariantami:
Argument jest istotny tylko na niektórych platformach, ale na tych, na których nie ma to znaczenia, mój kompilator będzie narzekał, a ponieważ mam ostrzeżenia skonwertowane na błędy, uniemożliwi to jego budowę.
Konwersja ostrzeżeń na błędy wymaga włazu awaryjnego dla „nie tego, wiem lepiej niż kompilator w tym przypadku”.
źródło
Wiele niezbędnych bibliotek Java nigdy nie zostało zaktualizowanych w celu wyeliminowania potrzeby tworzenia niebezpiecznych typecastów. Tłumienie tych ostrzeżeń jest konieczne, aby inne ważniejsze ostrzeżenia zostały zauważone i poprawione.
źródło
Wykonuję pracę osadzoną i wydaje mi się, że pamiętam jakiś czas, kiedy wyłączyłem ostrzeżenia, ponieważ robiłem coś, co wydawało się bezużyteczne dla kompilatora, ale które faktycznie miało rzeczywiste efekty w sprzęcie.
Jedyny inny czas to praca z podstawami kodu z odmiennymi pomysłami na pewne struktury danych (np. Jak reprezentować tablice bajtów - znak lub znak bez znaku?). W takich przypadkach mogę wyłączyć ostrzeżenia, ponieważ alternatywą jest spędzanie dni na przeglądaniu kodu i modyfikowaniu jednej części lub wprowadzaniu setek rzutów.
źródło
Istnieje wiele powodów, aby selektywnie wyłączać ostrzeżenia kompilatora, nawet w przypadku projektów, które dążą do najlepszych praktyk.
Kompilatory przetwarzają ostrzeżenia w subtelny sposób na różne sposoby. Przekazywanie fałszywie dodatnich ostrzeżeń, które nie wpływają na inne kompilatory. W takim przypadku sensowne może być wyłączenie ostrzeżenia dla tych kompilatorów, zamiast edytowania poprawnego kodu w celu wyciszenia fałszywie dodatniego ostrzeżenia, które wpływa tylko na niektóre kompilatory, szczególnie dla starszych kompilatorów, które ostatecznie nie będą obsługiwane.
Niektóre ostrzeżenia związane z higieną kodu (martwy kod, zduplikowana treść instrukcji warunkowych, porównania przekraczające limity typów) można bezpiecznie zignorować, ponieważ są nieszkodliwe, a kompilator je zoptymalizuje.
Generowanie kodu, który nie wywołuje tych nieszkodliwych ostrzeżeń, jest oczywiście również opcją, ale może być większym kłopotem niż wartością.
Być może używasz dobrze znanej implementacji sumy kontrolnej qsort lub md5, która jest zawarta w twoim projekcie. Kod jest używany w wielu projektach i wiadomo, że działa dobrze, ale mogą wystąpić pewne wybredne ostrzeżenia, które zwykle poprawiasz dla własnego kodu.
Jednak w przypadku kodu zewnętrznego wyłączenie ostrzeżenia może być mniej kłopotliwe (zakładając, że jest to zdecydowanie nieszkodliwe).
Mimo że na przykład obsługa GCC / Clang
-isystem
, różnice w nagłówkach systemu powodują ostrzeżenia, które można zignorować (być może funkcja ma podpisaną wartość zwrotną w jednym systemie, ale nie w innym), wywołując-Wsign-compare
ostrzeżenia.Innym przypadkiem mogą być makra zdefiniowane w nagłówkach systemowych, możesz skopiować i wkleić makra do własnego kodu, aby je zmodyfikować, ale wszystko uważało, że lepiej nie martwić się o utrzymanie makr z bibliotek stron trzecich ... więc lepiej po prostu wyciszyć ostrzeżenie (być może makro nie trafia w obsadę powodując
-Wsign-conversion
np.).Możesz ostrzegać przed nieużywanymi parametrami, jednak przy usuwaniu całej biblioteki w jednym pliku zawierającym tylko funkcje pośredniczące - nie jest pomocne wymuszanie
(void)arg1; (void)arg2; (void)arg3; ...
w treści każdej funkcji pośredniczącej.Lepiej po prostu pomiń
-Wunused-parameter
w tym przypadku.Należy zauważyć, że we wszystkich tych przykładach jego zakładał wyłączenie ostrzeżenia nie zamierza ukrywać rzeczywiste błędy, np:
-Wredundant-decls
,-Wunused-parameter
,-Wdouble-promotion
, być może-Wpedantic
... i że wiesz, co robisz!źródło
Prawidłowe czy nie, czasami robi się to w celu ominięcia dyrektywy „traktuj ostrzeżenia jak błędy” na serwerze kompilacji.
Poza tym nie mogę wymyślić żadnego z nich. Wyłączone ostrzeżenia są zwykle oznaką „brzydkiego haxa” ...
źródło
Ostatnim razem, kiedy wyłączaliśmy niektóre ostrzeżenia, było to spowodowane tym, że stażysta zostawił nam zły kod. Mam go o wiele lepiej, a wyraźne granice konwersji zastępują przypadkową reprezentację danych.
W międzyczasie musieliśmy go skompilować i chcieliśmy włączyć opcję „ostrzeżenia są błędami”, dlatego niektóre ostrzeżenia zostały pominięte.
źródło
Obecnie jedynym ostrzeżeniem, które zignorowałem, jest
Ponieważ Microsoft nie implementuje specyfikacji C ++ (dokumentacja mówi nawet, że nie!) I zezwala funkcjom na deklarowanie określonych rzutów, a wszystkie funkcje mogą rzucać tylko throw () lub throw (...), tzn. Nic lub wszystko.
Z HelpViewer 1.1:
źródło