Kiedy asercje powinny pozostać w kodzie produkcyjnym? [Zamknięte]

166

Na stronie comp.lang.c ++. Moderowana jest dyskusja na temat tego, czy asercje, które w C ++ istnieją domyślnie tylko w kompilacjach do debugowania, powinny być utrzymywane w kodzie produkcyjnym, czy nie.

Oczywiście każdy projekt jest wyjątkowy, więc moje pytanie nie dotyczy tego, czy należy zachować asercje, ale w jakich przypadkach jest to zalecane / nie jest to dobry pomysł.

Przez twierdzenie mam na myśli:

  • Sprawdzenie w czasie wykonywania, które testuje warunek, który, jeśli jest fałszywy, ujawnia błąd w oprogramowaniu.
  • Mechanizm zatrzymywania programu (może po naprawdę minimalnym czyszczeniu).

Niekoniecznie mówię o C lub C ++.

Osobiście uważam, że jeśli jesteś programistą, ale nie jesteś właścicielem danych (co ma miejsce w przypadku większości komercyjnych aplikacji komputerowych), powinieneś je włączyć, ponieważ błędne stwierdzenie pokazuje błąd i nie powinieneś iść z błędem, z ryzykiem uszkodzenia danych użytkownika. Zmusza to do zdecydowanego przetestowania przed wysyłką i sprawia, że ​​błędy są bardziej widoczne, a tym samym łatwiejsze do wykrycia i naprawienia.

Jaka jest Twoja opinia / doświadczenie?

Twoje zdrowie,

Carl

Zobacz powiązane pytanie tutaj


Odpowiedzi i aktualizacje

Hej Graham,

Stwierdzenie jest błędem, czystym i prostym i dlatego powinno być traktowane jak jedno. Ponieważ błąd powinien być obsługiwany w trybie wydania, tak naprawdę nie potrzebujesz asercji.

Dlatego wolę słowo „błąd”, gdy mówię o asercjach. To sprawia, że ​​wszystko jest znacznie jaśniejsze. Dla mnie słowo „błąd” jest zbyt niejasne. Brakujący plik jest błędem, a nie błędem i program powinien sobie z tym poradzić. Próba wyłuskania pustego wskaźnika jest błędem, a program powinien przyznać, że coś pachnie jak zepsuty ser.

Dlatego należy przetestować wskaźnik z asercją, ale obecność pliku z normalnym kodem obsługi błędów.


Nieco nie na temat, ale ważny punkt w dyskusji.

Jako ostrzeżenie, jeśli twoje asercje włamują się do debugera, gdy zawodzą, dlaczego nie. Ale jest wiele powodów, dla których plik nie może istnieć, a które są całkowicie poza kontrolą twojego kodu: prawa do odczytu / zapisu, pełny dysk, odłączone urządzenie USB itp. Ponieważ nie masz nad nim kontroli, uważam, że nie jest właściwym sposobem radzenia sobie z tym.

Carl


Tomasz,

Tak, mam Code Complete i muszę powiedzieć, że zdecydowanie nie zgadzam się z tą konkretną radą.

Powiedzmy, że niestandardowy alokator pamięci spieprzy i zeruje fragment pamięci, który jest nadal używany przez inny obiekt. Zdarza mi się wyzerować wskaźnik, który regularnie odwołuje się do tego obiektu, a jednym z niezmienników jest to, że ten wskaźnik nigdy nie jest zerowy i masz kilka twierdzeń, aby upewnić się, że tak pozostanie. Co zrobisz, jeśli wskaźnik nagle stanie się pusty. Po prostu jeśli () go otaczasz, mając nadzieję, że to zadziała?

Pamiętaj, że mówimy tutaj o kodzie produktu, więc nie ma potrzeby włamywania się do debuggera i sprawdzania stanu lokalnego. To jest prawdziwy błąd na komputerze użytkownika.

Carl

nieznanych
źródło
3
Jest interesujący, powiązany post w Software Engineering SE (chociaż dyskusja koncentruje się na C ++): Czy w kompilacjach wydań powinny być stwierdzenia
sonny

Odpowiedzi:

84

Asercje to komentarze, które nie stają się nieaktualne. Dokumentują, które stany teoretyczne są zamierzone, a które nie powinny wystąpić. Jeśli kod zostanie zmieniony, tak aby wskazać dozwoloną zmianę, programista zostanie wkrótce poinformowany i musi zaktualizować potwierdzenie.

MSalters
źródło
16
@jkschneider: testy jednostkowe służą do testowania rzeczy w zakresie kodu programu. asercje mają na celu zapewnienie, że założenia, na których opiera się kod, są rzeczywiście prawdziwe, zanim kod będzie kontynuował przetwarzanie zgodnie z tymi założeniami. Są "dokumentacją" w tym sensie, że jeśli okaże się, że tak nie jest, program przerwie działanie, przedstawi założenie i wskaże, że założenie się nie sprawdziło. Oczywiście możesz również przeczytać to stwierdzenie jako dokumentację tego w kodzie.
2
To najlepsza odpowiedź, ponieważ wiąże twierdzenia z komentarzami, co jest pomocnym sposobem myślenia o nich. Są krokiem naprzód od komentarzy, ponieważ są stale testowane maszynowo podczas opracowywania, ale zawsze powinny mieć znaczenie dla ludzkich czytelników. Podobnie jak komentarze, nie powinny być częścią logiki ani ostatecznego wykonania. Podobnie jak komentarze, możesz je zostawić lub usunąć w zależności od tego, czy język jest kompilowany lub interpretowany, Twoje plany wdrożenia, strategia zaciemniania itp. Widziałem jeden przypadek, w którym komentarz faktycznie spowodował błąd, ale był to dziwny.
DaveWalley,
1
Mówiąc dokładniej, potwierdzenia mają charakter informacyjny i nie są funkcjonalne . Samo potwierdzenie nie ma wpływu na przebieg programu ani wyniki. Z drugiej strony wyjątek zmienia przebieg programu, a tym samym wyniki.
jojo,
59

Pozwólcie, że zacytuję Code Complete Steve'a McConnella. Sekcja dotycząca twierdzeń to 8.2.

Zwykle nie chcesz, aby użytkownicy widzieli komunikaty potwierdzeń w kodzie produkcyjnym; asercje są używane głównie podczas opracowywania i konserwacji. Asercje są zwykle kompilowane do kodu w czasie projektowania i kompilowane poza kodem do produkcji.

Jednak w dalszej części tej samej sekcji podano następujące porady:

Aby uzyskać wysoce niezawodny kod, potwierdź, a następnie obsłuż błąd mimo wszystko.

Myślę, że dopóki wydajność nie jest problemem, zostaw potwierdzenie, ale zamiast wyświetlać komunikat, zapisz go w pliku dziennika. Myślę, że ta rada jest również w Code Complete, ale teraz jej nie znajduję.

Thomas Owens
źródło
7
Myślę, że to, co drugi cytat z Code Complete oznacza, że ​​powinieneś mieć assert - który zostanie wkompilowany w kod produkcyjny - a także powinieneś mieć „if (! Condition) {AttemptGracefulRecovery ();}”, tj. Don nie pozwól, aby naruszenie niezmienników programu spowodowało awarię programu.
jojo,
34

Pozostaw asercje włączone w kodzie produkcyjnym, chyba że zmierzyłeś, że program działa znacznie szybciej, gdy są wyłączone.

jeśli nie warto mierzyć, aby udowodnić, że jest bardziej wydajny, nie warto poświęcać przejrzystości na rzecz gry wydajności. ”- Steve McConnell 1993

http://c2.com/cgi/wiki?ShipWithAssertionsOn

David Cary
źródło
11
W rzeczywistości najgorsze, co się dzieje, to awaria kodu z powodu czegoś, co NIE jest potwierdzeniem. Jeśli kod definitywnie ulegnie późniejszej awarii ze 100% prawdopodobieństwem, to potwierdzenie musi bezwzględnie istnieć. Jeśli wyrzucisz wskaźnik, musisz niejawnie stwierdzić, że nie jest on wcześniej pusty. Jeśli podzielisz przez liczbę, zapewniasz, że nie jest to zero. Usuń potwierdzenia, a wszystkie lokalizacje awarii będą NIEDOKUMENTOWANE. Prawdziwym problemem nie jest taka struktura programu, która pozwala na awarię podsystemów i ponowne uruchomienie przez stróża.
Rob,
5
assert ref != null;jest inny niż if (ref == null) throw new IllegalArgumentException();Nie powinieneś używać pierwszego dla warunków wstępnych, które mogą być fałszywe. Musisz używać assertdo rzeczy, które nie mogą być fałszywe. Przykład, int i = -1 * someNumber; i = i * i;a później, aby przypomnieć ludziom, że ijest to pozytywne,assert i > 0;
Kapitan Man,
1
„W rzeczywistości najgorsze, co się dzieje, to awaria kodu z powodu czegoś, co NIE jest potwierdzeniem. Jeśli kod na pewno ulegnie później awarii ze 100% prawdopodobieństwem, to potwierdzenie musi bezwzględnie istnieć”. - to fałszywa dychotomia.
Rob Grant
2
@RobertGrant: W przypadku wielu programów awaria nie jest najgorszą rzeczą, jaka może się zdarzyć. W przypadku programu, który ma sprawdzać solidność projektu budynku lub mostu, błędne zgłoszenie, że projekt jest dobry, może być najgorszą rzeczą, jaką mógłby zrobić. W przypadku programu, który jest narażony na świat zewnętrzny, ale ma dostęp tylko do odczytu do poufnych danych, wyciek tych danych może być gorszy niż cokolwiek innego, co program mógłby zrobić. Pogląd, że katastrofa bez znaczącego wskazania przyczyny jest „najgorszą rzeczą, jaka może się zdarzyć”, ignoruje wiele niebezpieczeństw, które są znacznie gorsze.
supercat
@supercat Nie zgadzam się z cytowanym komentarzem.
Rob Grant
21

Jeśli nawet myślisz o pozostawieniu asercji w produkcji, prawdopodobnie myślisz o nich źle. Cały sens twierdzeń polega na tym, że możesz je wyłączyć w produkcji, ponieważ nie są one częścią twojego rozwiązania. Są narzędziem programistycznym, służącym do weryfikacji poprawności założeń. Ale zanim zaczniesz produkcję, powinieneś już mieć zaufanie do swoich założeń.

To powiedziawszy, jest jeden przypadek, w którym włączę asercje w środowisku produkcyjnym: jeśli napotkamy odtwarzalny błąd w środowisku produkcyjnym, którego odtworzenie w środowisku testowym jest trudne, pomocne może być odtworzenie błędu z włączonymi asercjami w produkcji, aby sprawdzić, czy dostarczają przydatnych informacji.

Bardziej interesujące pytanie brzmi: kiedy w fazie testowania wyłączasz asercje?

MiguelMunoz
źródło
4
Myślę, że asercje nigdy nie powinny być zawarte w kodzie produkcyjnym. asercje NIE są błędami, są przeznaczone dla programistów. Asercje powinny istnieć tylko w kodzie testowym. Awaria aplikacji jest spowodowana niepowodzeniem asercji i niedopuszczalnym rozwojem. Programiści muszą dołożyć wszelkich starań, aby z wdziękiem obsługiwać błędy.
iksnae
9
Jeśli jest nieuniknione, że nastąpi awaria przy zerowym wskaźniku przekazanym do fn; nie ma wyboru, czy zająć się tym jawnie. Albo masz jakiś sposób na z wdziękiem poradzenie sobie z tym stanem (ponieważ może on pochodzić z danych wejściowych ze świata zewnętrznego), albo rozbijasz się w DOKUMENTOWANYM miejscu z asercją, a nie w przypadkowym miejscu, które mogło zepsuć rzeczy po drodze. Sposób obsługi asertu powinien jednak zależeć od decyzji poszczególnych modułów. Może twój watchdog restartuje proces lub czyścisz kawałek pamięci dla tego modułu, aby zresetować go do stanu początkowego (miękki obiekt „restart”).
Rob
1
Myślę, że jest to ograniczony pogląd na użycie potwierdzeń. Zawsze rejestruję potwierdzenia zarówno w konsoli, jak i w chmurze i zostawiam je w środowisku produkcyjnym. Pozostawienie potwierdzeń na potwierdza, że ​​moje założenia pozostają poprawne nawet w kodzie produkcyjnym i podczas użytkowania produkcyjnego. To, że kod został kilkakrotnie pomyślnie uruchomiony podczas debugowania z włączonymi potwierdzeniami, nie oznacza, że ​​użytkownicy nie znajdą sposobu na przekazanie różnych wartości przez tę samą ścieżkę kodu.
SafeFastExpressive
Cała instrukcja assert polega na tym, że możesz włączać i wyłączać sprawdzanie. Jeśli zostawisz je włączone w produkcji, po co używać instrukcji assert?
MiguelMunoz
1
Asercje często spowalniają system. Ponieważ nie są przeznaczone do produkcji, mogą być powolne i nieefektywne, co może być konieczne do wykonania niektórych testów. Na przykład firma Microsoft dodała kiedyś do programu Excel funkcję szybkiego ponownego obliczania. Gdy jedna komórka uległa zmianie, funkcja ta ograniczyła ponowne obliczenie tylko do komórek, które tego potrzebowały. Przetestowali to z twierdzeniem, które przeliczyło cały arkusz kalkulacyjny i porównało wyniki. To sprawiło, że wersja rozwojowa działała bardzo wolno, ale również wyeliminowała wiele błędów. Kiedy wypuścili tę funkcję, okazała się bardzo niezawodna.
MiguelMunoz
16

Asercje powinny nigdy nie pozostać w kodzie produkcyjnym. Jeśli konkretne stwierdzenie wydaje się być przydatne w kodzie produkcyjnym, to nie powinno to być twierdzenie; powinno być sprawdzenie błędu czasu pracy, czyli coś zakodowane tak: if( condition != expected ) throw exception.

Termin „asercja” zaczął oznaczać „kontrolę tylko w czasie rozwoju, która będzie nie zostanie przeprowadzona w terenie”.

Jeśli zaczniesz myśleć, że asercje mogą dotrzeć do pola, to nieuchronnie zaczniesz też tworzyć inne niebezpieczne myśli, na przykład zastanawiać się, czy dane twierdzenie jest naprawdę warte wyrażenia. Nie ma twierdzenia, które nie jest warte wyrażenia. Nigdy nie powinieneś zadawać sobie pytania „czy mam to potwierdzić, czy nie?” Powinieneś tylko zadawać sobie pytanie: „Czy jest coś, o czym zapomniałem potwierdzić?”

Mike Nakis
źródło
6

O ile profilowanie nie wykaże, że asercje powodują problemy z wydajnością, mówię, że powinny one również pozostać w wersji produkcyjnej.

Myślę jednak, że wymaga to również, abyś radził sobie z niepowodzeniami asercji z pewnym wdziękiem. Na przykład powinny one skutkować ogólnym typem okna dialogowego z opcją (automatycznego) zgłaszania problemu programistom, a nie tylko zamykaniem lub zawieszaniem programu. Powinieneś także uważać, aby nie używać asercji do warunków, na które faktycznie zezwalasz, ale prawdopodobnie nie lubisz lub nie uważasz za niepożądane. Warunki te powinny zostać uwzględnione w innych częściach kodu.

Anders Sandvig
źródło
Jak widzę, głównym celem asercji produkcyjnej jest awaryjne zabezpieczenie: zezwolenie na kontynuację programu z dużym prawdopodobieństwem spowoduje szkodę na tyle poważną, że zapobieganie jej jest ważniejsze niż cokolwiek innego, co może robić program. Jeśli to możliwe, dobrze byłoby mieć dobry komunikat o błędzie, ale ma to drugorzędne znaczenie.
supercat
5

W moim C ++ definiuję REQUIRE (x), który jest podobny do assert (x), z tą różnicą, że zgłasza wyjątek, jeśli asercja nie powiedzie się w kompilacji wydania.

Ponieważ nieudane potwierdzenie wskazuje na błąd, powinno być traktowane poważnie nawet w kompilacji wydania. Kiedy wydajność mojego kodu ma znaczenie, często używam REQUIRE () dla kodu wyższego poziomu i assert () dla kodu niższego poziomu, który musi działać szybko. Używam również REQUIRE zamiast assert, jeśli stan błędu może być spowodowany danymi przesłanymi z kodu napisanego przez osobę trzecią lub uszkodzeniem pliku (optymalnie zaprojektowałbym kod specjalnie tak, aby zachowywał się dobrze w przypadku uszkodzenia pliku, ale my nie zawsze mam na to czas).

Mówią, że nie powinieneś pokazywać tych wiadomości użytkownikom końcowym, ponieważ ich nie zrozumieją. Więc? Użytkownicy końcowi mogą wysłać Ci wiadomość e-mail ze zrzutem ekranu lub tekstem komunikatu o błędzie, co pomoże w debugowaniu. Jeśli użytkownik powie po prostu „awaria”, masz mniej możliwości, aby to naprawić. Lepiej byłoby wysyłać komunikaty o niepowodzeniu do siebie automatycznie przez Internet, ale działa to tylko wtedy, gdy użytkownik ma dostęp do Internetu i możesz uzyskać jego zgodę.

Qwertie
źródło
Mówią też, że nie powinno się pokazać te wiadomości dochodzić hakerów, ponieważ są one cenne wskazówki na włamanie.
DaveWalley
4

Jeśli chcesz je zachować, zastąp je obsługą błędów. Nie ma nic gorszego niż program po prostu znikający. Nie widzę nic złego w traktowaniu niektórych błędów jako poważnych błędów, ale powinny być skierowane do sekcji programu, która jest przygotowana do radzenia sobie z nimi poprzez zbieranie danych, rejestrowanie ich i informowanie użytkownika, że ​​Twoja aplikacja ma niepożądany stan i wychodzi.

bruceatk
źródło
2

Pod warunkiem, że są obsługiwane tak jak każdy inny błąd, nie widzę z tym problemu. Należy jednak pamiętać, że nieudane asercje w C, podobnie jak w innych językach, po prostu zakończą działanie programu, a to zwykle nie wystarcza w przypadku systemów produkcyjnych.

Istnieją pewne wyjątki - na przykład PHP pozwala na utworzenie niestandardowego modułu obsługi błędów asercji, dzięki czemu można wyświetlać niestandardowe błędy, wykonywać szczegółowe rejestrowanie itp. Zamiast po prostu wychodzić.

Steve M.
źródło
2

Nasze oprogramowanie serwera bazy danych zawiera zarówno potwierdzenia produkcyjne, jak i debugowania. Asercje debugowania są po prostu tym - są usuwane w kodzie produkcyjnym. Twierdzenia produkcyjne mają miejsce tylko wtedy, gdy (a) istnieje jakiś warunek, który nigdy nie powinien istnieć oraz (b) nie jest możliwe niezawodne wyjście z tego stanu. Twierdzenie produkcyjne wskazuje, że napotkano błąd w oprogramowaniu lub nastąpiło uszkodzenie danych.

Ponieważ jest to system baz danych, a my przechowujemy dane potencjalnie krytyczne dla przedsiębiorstwa, robimy wszystko, co w naszej mocy, aby uniknąć uszkodzenia danych. Jeśli istnieje warunek, to może spowodować, że będziemy przechowywać niepoprawne dane, natychmiast potwierdzamy, wycofujemy wszystkie transakcje i zatrzymujemy serwer.

To powiedziawszy, staramy się również unikać asercji produkcyjnych w procedurach krytycznych dla wydajności.

Graeme Perrow
źródło
5
Nazwałbym twoje „potwierdzenie produkcyjne” „wyjątkiem” i zakodowałbym je jako takie.
DaveWalley,
1
Prawdopodobnie masz rację, ale produkt został pierwotnie napisany w C. Nawet gdy zmieniliśmy go na C ++, kompilatory, których używaliśmy na niektórych naszych platformach, nie obsługiwały poprawnie wyjątków. Większość starego kodu nie została przepisana w C ++, więc te twierdzenia są nadal używane.
Graeme Perrow
1

Potwierdzenia traktuję jako testy jednostkowe in-line. Przydatne do szybkiego testowania podczas opracowywania, ale ostatecznie te twierdzenia powinny zostać refaktoryzowane, aby można je było przetestować zewnętrznie w testach jednostkowych.

Weston
źródło
Assert: Podaj fakt lub przekonanie. Nie służą do testowania (tylko), ale do stwierdzenia, co uważasz za prawdę (tj. Swoich założeń), aby program nie był kontynuowany, jeśli założenia są błędne z jakiegoś powodu. Na przykład jest to prawidłowe użycie asercji: assert (pow (1,0) <1). To naprawdę nie jest odpowiednie miejsce do sprawdzania błędów, ponieważ jeśli to nieprawda, to prawie cała współczesna matematyka jest błędna i ... cóż, jak w ogóle zacząłbyś sobie z tym radzić? Obsługa tego błędnego założenia wykracza poza zakres programu; bierzesz to na wiarę. Ale i tak zweryfikujesz.
1

Uważam, że najlepiej radzić sobie ze wszystkimi błędami w zakresie i używać potwierdzeń dla założeń, które twierdzimy, że SĄ prawdziwe.

tzn. jeśli Twój program otwiera / odczytuje / zamyka plik, to brak możliwości otwarcia pliku jest objęty zakresem - jest to realna możliwość, której zignorowanie byłoby, innymi słowy, niedbałe. Powinien więc mieć powiązany kod sprawdzający błędy.

Załóżmy jednak, że funkcja fopen () jest udokumentowana jako zawsze zwracająca prawidłowy, otwarty uchwyt pliku. Otwierasz plik i przekazujesz go do funkcji readfile ().

Ta funkcja readfile, w tym kontekście i prawdopodobnie zgodnie ze specyfikacją projektu, może w dużym stopniu zakładać, że uzyska prawidłowy plik ptr. Tak więc marnotrawstwo byłoby dodawanie kodu obsługi błędów dla przypadku negatywnego w tak prostym programie. Powinien jednak przynajmniej udokumentować założenie, w jakiś sposób - upewnić się - że tak jest, zanim będzie kontynuował jego realizację. Nie powinien FAKTYCZNIE zakładać, że będzie zawsze poprawny, w przypadku, gdy zostanie wywołany nieprawidłowo lub na przykład zostanie skopiowany / wklejony do innego programu.

Tak więc readfile () {assert (fptr! = NULL); ..} jest odpowiednie w tym przypadku, podczas gdy pełna obsługa błędów nie jest (ignorowanie faktu, że faktyczne odczytanie pliku i tak wymagałoby systemu obsługi błędów).

I tak, te zapewnienia powinny pozostać w kodzie produkcyjnym, chyba że jest to absolutnie konieczne, aby je wyłączyć. Nawet wtedy powinieneś prawdopodobnie wyłączać je tylko w sekcjach krytycznych dla wydajności.

Lee
źródło
1

Załóżmy, że w produkcji znajduje się fragment kodu, który trafia w potwierdzenie, które normalnie zostałoby uruchomione. Asercja znalazła błąd! Tyle że tak nie jest, ponieważ asercja jest wyłączona.

Więc co się teraz dzieje? Albo program (1) zawiesi się w sposób nieinformacyjny w miejscu dalej oddalonym od źródła problemu, albo (2) będzie działał wesoło do końca, prawdopodobnie dając zły wynik.

Żaden scenariusz nie jest zachęcający. Pozostaw asercje aktywne nawet w produkcji.

Killer Marmot
źródło
0

Rzadko używam asercji do czegokolwiek innego niż sprawdzanie typu czasu kompilacji. Użyłbym wyjątku zamiast potwierdzenia tylko dlatego, że większość języków jest zbudowana tak, aby je obsługiwać.

Podaję przykład

file = create-some-file();
_throwExceptionIf( file.exists() == false, "FILE DOES NOT EXIST");

przeciwko

file = create-some-file();
ASSERT(file.exists());

Jak aplikacja poradzi sobie z asercją? Wolę starą try catchmetodę radzenia sobie z krytycznymi błędami.

Maleństwo
źródło
2
Wyjątki dotyczą nietypowych sytuacji, które spodziewasz się napotkać w działającej aplikacji, jak na przykład tutaj. Asercje dotyczą sytuacji, których spodziewasz się nigdy nie spotkać. Jeśli więc je napotkasz, w Twoim kodzie musi być błąd. W twoim przykładzie wyjątek jest wyraźnie właściwym podejściem. Ale asercje są nadal bardzo przydatne do wyłapywania błędów.
MiguelMunoz
0

W większości przypadków, gdy używam asercji w java (słowo kluczowe assert), automatycznie dodam po. W zależności od przypadku może to być komunikat logowania, wyjątek ... lub nic.

Według mnie wszystkie twoje twierdzenia są krytyczne w wydaniu deweloperskim, a nie w produkcji. Część z nich trzeba zachować, inne wyrzucić.

Nicolas
źródło
0

ASSERTIONS nie są błędami i nie powinny być traktowane jako błędy. Gdy zostanie wyrzucone potwierdzenie, oznacza to, że jest błąd w kodzie lub alternatywnie w kodzie wywołującym twój kod.

Istnieje kilka punktów, aby uniknąć włączania asercji w kodzie produkcyjnym: 1. Nie chcesz, aby użytkownik końcowy widział komunikat typu „ASSERTION failed MyPrivateClass.cpp wiersz 147. Użytkownik końcowy NIE jest inżynierem ds. Kontroli jakości. 2. ASSERTION może wpływać na wydajność

Jest jednak jeden mocny powód, aby zostawić asercje: ASSERTION może wpłynąć na wydajność i synchronizację i niestety czasami ma to znaczenie (szczególnie w systemach wbudowanych).

Zwykle głosuję za pozostawieniem asercji włączonej w kodzie produkcyjnym, ale upewniam się, że wydruki tych stwierdzeń nie są ujawniane użytkownikowi końcowemu.

~ Yitzik

Yitshak Yarom
źródło
Nie, twierdzenia dotyczą zakładanych faktów. Jeśli nasz kod zwraca 27, kiedy zakłada się, że ZAWSZE zwróci 25, problemem może być również błąd w naszych fizycznych założeniach dotyczących wszechświata: być może te dwa bity zostały przełączone na 5 możliwych wartości, po raz pierwszy w historii obliczeń. Twierdzenie ma na celu potwierdzenie, że Twój kod nadal działa zgodnie z założeniami, dla których został napisany. Jeśli fizyka wypadnie przez okno, twój kod powinien to zauważyć, zostaw dysk w spokoju i zakończ pracę;) Ale tak, to nie jest błąd w kodzie, a jakiego rodzaju obsługę błędów możesz zrobić?
Pozwól mi doprecyzować moją opinię: 1. Asercja sprawdź nasze przypuszczenia. Jeśli nasze założenia są błędne, oznacza to, że w NASZYM kodzie jest błąd. 2. Nasz kod nie powinien sugerować użycia naszego kodu. tzn. funkcja nie powinna zawieść przy potwierdzeniu, jeśli coś jest nie tak w danych wejściowych od użytkownika. Zwrócimy błąd i użytkownik powinien sobie poradzić (może potwierdzić sukces) 3. Wolę pozostawić asercję w produkcji - ale zachowanie prawdopodobnie zostanie zmodyfikowane. Zgadzam się, że nie ma odpowiedniej obsługi błędów. Niepowodzenie asercji == błąd ... ale system może sam się uruchomić ponownie, zamiast zatrzymywać się i czekać na ponowne uruchomienie.
Yitshak Yarom
1
NIE KONIECZNIE oznacza to, że jest błąd. Na przykład wiele projektów, w które jestem zaangażowany, ma w dokumentacji listę zakładanych faktów. Założenia te mają na celu ochronę kodu programistów przed nazywaniem go błędnym, gdy ludzie biznesu mogli im powiedzieć coś złego lub gdy na przykład nie są dostępne żadne informacje od stron trzecich o określonych zmiennych. Twierdzenia można wykorzystać do sprawdzenia, czy program powinien / nie powinien działać, czy systemy innych firm są poprawne, a nie tylko, czy poprawność IT jest poprawna.
-8

Stwierdzenie jest błędem, czystym i prostym i dlatego powinno być traktowane jak jedno.

Ponieważ błąd powinien być obsługiwany w trybie wydania, tak naprawdę nie potrzebujesz asercji.

Główną korzyścią, jaką widzę w przypadku asercji, jest warunkowa przerwa - są one znacznie łatwiejsze do skonfigurowania niż drążenie okien VC w celu skonfigurowania czegoś, co zajmuje 1 wiersz kodu.

graham.reeds
źródło
2
Używanie potwierdzeń jako warunkowych punktów przerwania jest naprawdę irytujące z kilku powodów. Najważniejsze jest to, że te potwierdzenia dezorientują innych programistów w zespole - skąd mieliby wiedzieć, czy jest to błąd, gdy to potwierdzenie zostało uruchomione, czy też ktoś zostawił swój warunkowy punkt przerwania w kodzie?
lego
Nie byłoby, gdyby w kodzie nie było potwierdzeń. A gdybyś używał ich tylko do monitorowania kodu, zobaczyłbyś je (chyba że wpisałeś je do drzewa źródłowego). Pracowałem w miejscach, które potwierdzają praktycznie wszystko. Konieczność około 60 kliknięć na początku programu, ponieważ serwer dokumentacji pomocy jest niedostępny, bardzo szybko staje się męczący.
graham.reeds