Wpis z mikrobloga

Teraz dość filozoficzne pytanie z C++ i w ogóle programowania będzie.

Załóżmy, że chcę mieć funkcję, która wykonuje jedną z dwóch operacji w zależności od tego, który z dwóch teoretycznie przeciwstawnych warunków jest spełniony. Jeżeli żaden to niechybnie oznacza, że coś się z-----o, trzeba zakończyć program i zwrócić informację o błędzie. Napisałem:

void function() {

....if(coś) {

........operacja1();

....} else if(coś_innego) {

........operacja2();

....} else {

........std::unexpected();

....}

}

Kod dobrze spełnia swoje zadanie. Jeżeli coś jest nie tak to wywala się i wypisuje, że sterowanie zabrnęło tam, gdzie dojść nigdy nie powinno. Po poprawieniu błędów, w gotowym programie unexpected() nigdy się nie wykona. Na pewno tak jest sto razy lepiej niż zostawienie funkcji w ogóle bez else, bo wyskakują warningi, a po ominięciu if i else if mam naruszenie ochrony pamięci i nie jest jasne na pierwszy rzut oka gdzie.

Ale ładnie to tak? Może tak zostać, czy jest jakiś lepszy, ogólnie przyjęty sposób rozwiązywania problemów tego typu? Wydaje mi się jakieś takie brudne to rozwiązanie, zaciemniające kod. A zależy mi, żeby zrobić to porządnie. Propozycje?

#stylkodowania #programowanie #cpp
  • 17
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@Onoki: jeżeli nie ma szansy na to, że się wykona z inną wartością (ew. jeśli po całym ifie już nie robisz nic istotnego) to możesz po prostu wywalić

else
.
  • Odpowiedz
@rss: Ciekawe. Dałem else, bo ta funkcja tak naprawdę nie jest void i chciałem uniknąć

warning: control reaches end of non-void function


ale okazało się, że nawet bez else to ostrzeżenie się nie pojawia. :)
  • Odpowiedz
@Onoki: Kompilator jest w stanie wydedukować (w określonych przypadkach), ƶe if/else if obsługuje wszystkie moƶliwe przypadki.

Przy okazji, nie lepiej rzucić wyjątkiem, niƶ wołać

std::unexpected
? (które jest, nota bene, deprecated)
  • Odpowiedz
@KrzaQ2: Rzucanie wyjątku jest chyba działaniem trochę na około, bo i tak nie mam zamiaru go łapać, a nieprzechwycony wyjątek wywołuje właśnie unexpected(). Dochodzą do tego problemy jakiego typu ma być wyjątek i dlaczego właśnie takiego. Tak zupełnie formalnie to powinienem stworzyć klasę Z-----------------n... Za dużo babrania.

@Ginden: Kompletnie nie rozumiem o co Ci chodzi.

Może rozwinę myśl: piszę grę, a funkcja funkcja przyjmuje obiekt, który w założeniu
  • Odpowiedz
@Ginden: No właśnie niestety nie. :( Teoretycznie obiekt przekazywany do funkcji powinien należeć do gracza A lub do gracza B. Praktycznie klasa tego obiektu ma konstruktor domyślny, który nie ustawia właściciela. I po to jest ten cały temat, że już raz mi się udało przekazać tej funkcji bezpański obiekt, w wyniku czego miałem naruszenie ochrony pamięci o niejasnym pochodzeniu i zmarnowałem kilkanaście minut na zlokalizowanie błędu. I po to jest
  • Odpowiedz
@Ginden: Ach tak, masz rację. Tylko, że otrzymuję dokładnie to samo (unexpected w miejscu Twojego komentarza // rzucasz błąd), a w dodatku przynależność do graczy jest sprawdzana trzy razy, a w mojej wersji jeden lub dwa.
  • Odpowiedz
@Onoki: (#) Czy sprawdzanie przynależności obiektu jest takie złożone obliczeniowo...?

PS. Ja bym się na Twoim miejscu zastanawiał, skąd się w ogóle biorą niczyje obiekty, bo prawdopodobnie masz gdzieś w logice aplikacji błąd.
  • Odpowiedz
Czy sprawdzanie przynależności obiektu jest takie złożone obliczeniowo...?


@Ginden: Nie, ale po co mam robić gorzej skoro mogę zrobić lepiej? :(

skąd się w ogóle biorą niczyje obiekty


Pracuję nad tym, ale na razie tak być musi. Jak w Heroes, masz stwory graczy i stwory neutralne. :D
  • Odpowiedz
Nie, ale po co mam robić gorzej skoro mogę zrobić lepiej? :(


@Onoki: Wiesz, czasem czytelność kodu jest ważniejsza niż dwa takty procesora... Można to oczywiście wrzucić do zmiennych pomocniczych i porównywać tylko wartości, żaden problem.
  • Odpowiedz
@Zbyszek223: To najgorsza rzecz jakiej uczą w szkołach. W ten sposób importujesz do głownej przestrzeni wszystko co jest w std o_O A tam przecież są bardzo generyczne nazwy:

sort, hex, distance, copy, move, fill, remove, min, max... nie sposób wymienić.
  • Odpowiedz