Jak můžu opustit funkci

x14

  • ***
  • 182
    • Zobrazit profil
    • E-mail
Re:Jak můžu opustit funkci
« Odpověď #60 kdy: 13. 07. 2018, 14:14:49 »
Já jsem tak rád, že nemusím dělat v C. V C++ dělám vše 100 % RAII a utéct z funkce můžu kdykoliv - uklízí destruktory.

V C jsem většinou dopadl tak, že jsem na začátku měl vynulované všechny proměnné a jednu stavovou proměnnou (často jen bool success=true) a kousek před koncem funkce label se jménem exitus, na který jsem skákal při předčasném ukončení. A za ním už byly jen samé delete, free, closehande, closefile...

Bylo to přehledné a bránilo to opomenutí v případě nečekaného selhání. Jiné goto než goto exitus jsem nikdy nepoužil a tento skok v naprosté většině případů znamenal chybu.
A zdroják pak byl čistě takto:
Kód: [Vybrat]
mem = alloc(...);
if(!mem)
{
     succes = false;
     goto exitus;
}


PetrM

Re:Jak můžu opustit funkci
« Odpověď #61 kdy: 13. 07. 2018, 14:31:49 »
#define check(podminka) if(!(podminka)) return

Tak ty jses dobry cune. Pouzivani maker je problematicke samo o sobe. Neda se to poradne debugovat. Atd. Takovehle makra mas v produkcnim kodu?

Makra taky nepreferuju, ale mají několik výhod, který se prostě nedají ignorovat.
Třeba to, že kdybych tohle zapouzdřil jako funkci, tak se nemůžu vrátit z funkce o level výš.
Nebo je to nejjednodušší způsob, jak udělat polymorfní funkci - místo add(a, b) pro int a pod jiným jménem pro float je tam makro, kde nezáleží na typech.
Anebo prostě fakt, že ošetření návratu přes setjmp() na embedded věcech sežere dost RAMky a třeba ve FreeRTOSu havaruje celá aplikace...
Pak taky není špatný zabalit funkci, které předáváš pointer na buffer a velikost bufferu společně se sizeof(), to taky ušetří hodně práce. Prostě
Kód: [Vybrat]
uint8_t buffer_8b[];
uint16_t buffer_16b[];
uint32_t buffer_32b[];
intptr_t buffer_ptr[];

fillZero(buffer_8b);
fillZero(buffer_16b);
fillZero(buffer_32b[]);
fillZero(buffer_ptr[]);

kde je makro
Kód: [Vybrat]
#define fillZero(buff) _fillZero(buff, sizeof(buff) / sizeof(buff[1]))
je přehlednější, než tam ručně cpát vnitřek té definice, nebo jako velikost rvát magický konstanty apod.

Jedno ze základních pravidel je, že je lepší jednu věc mít na jednom místě v kódu, i za cenu makra nebo (inline) funkce.

A co se debugování maker týká, pokud je zřejmý, co makro dělá (= odladěný a schovaný 1 LOC), nebo jenom zpouzdřuje funkci (do které skočíš a vidíš parametry), není to problém.

Kit

Re:Jak můžu opustit funkci
« Odpověď #62 kdy: 13. 07. 2018, 14:38:34 »
V C jsem většinou dopadl tak, že jsem na začátku měl vynulované všechny proměnné a jednu stavovou proměnnou (často jen bool success=true) a kousek před koncem funkce label se jménem exitus, na který jsem skákal při předčasném ukončení. A za ním už byly jen samé delete, free, closehande, closefile...

K čemu je dobré na začátku nulovat proměnné? Hodnoty jim definuji až za běhu a zpravidla je už neměním - snad až na řídicí proměnné cyklu a proměnné typu sum, které stejně musím vynulovat před sčítacím cyklem. Bool proměnné nepoužívám - když je vypustím bez náhrady, tak aplikace běží ještě lépe a radostněji.

Ten label exitus se však jistě hodil, i když si nedovedu moc představit, jak bych ho využil. Goto v mých programech nenajdeš.

Kit

Re:Jak můžu opustit funkci
« Odpověď #63 kdy: 13. 07. 2018, 14:54:19 »
Kód: [Vybrat]
#define check(podminka) if(!(podminka)) returnTak ty jses dobry cune. Pouzivani maker je problematicke samo o sobe. Neda se to poradne debugovat. Atd. Takovehle makra mas v produkcnim kodu?
Makra taky nepreferuju, ale mají několik výhod, který se prostě nedají ignorovat.
Třeba to, že kdybych tohle zapouzdřil jako funkci, tak se nemůžu vrátit z funkce o level výš.

Tohle makro je sice zajímavé, ale chybí mu návratová hodnota, takže už nikdo nepozná důvod, proč ta funkce neproběhla. U procedur v C považuji za standard, že návratový typ není void, ale int a obsahuje stavový kód. Makro by v mém provedení vypadalo asi takto:
Kód: [Vybrat]
#define check(podminka, errorCode) if(!(podminka)) return errorCodeNebylo by vhodnější to makro pojmenovat assert?

x14

  • ***
  • 182
    • Zobrazit profil
    • E-mail
Re:Jak můžu opustit funkci
« Odpověď #64 kdy: 13. 07. 2018, 15:43:41 »
K čemu je dobré na začátku nulovat proměnné?
Přece abych za exitusem nevolal free(mem) na náhodou adresu, nezavíral soubor, k jehož otevření nikdy nedošlo...


x14

  • ***
  • 182
    • Zobrazit profil
    • E-mail
Re:Jak můžu opustit funkci
« Odpověď #65 kdy: 13. 07. 2018, 15:48:22 »
Nebylo by vhodnější to makro pojmenovat assert?
To by určitě nebylo, když to není assert. Nápověda: assert se v release kódu odstraňuje.

.

Re:Jak můžu opustit funkci
« Odpověď #66 kdy: 13. 07. 2018, 22:27:50 »
Skor je to problem, ze pisem aplikacie v ktorych klienti uprednostnuju robustnost pred korektnostou a musia sa spamatat za kazdej situacie. 
Nedá mi to, abych znovu nevytáhl výrok, který zapadl a přitom aspiruje na výrok roku v tomto fóru.

NIKDO, opravdu NIKDO, nemůže upřednostňovat robustnost před správnou funkčnosti. Jedinou výjimkou by za určitých podmínek mohla být armáda, ale ani tam si to nikdo nedovolí. Až ta vaše mašina někoho zabije nebo se zničí, tak budete těžko vysvětlovat, že jste jen splnil zadání. Mimochodem, napsat robustní program je triviální, problém trochu je, že nic nedělá.

A na závěr, pokud je vašim cílem vysoká robustnost, vybral jste si špatný jazyk, C rozhodně robustní není. Ale už vám do toho nebudu mluvit, znám takové týpky, 15 let oprašuje svoje zlaté tele, zpravidla jsou to samouci, co znají ve svém kódu každý řádek, ale jinak jsou nepoužitelní. Jejich zákazníci se každý den modlí, aby je náhodou nesrazilo auto, protože to nikdo jiný není schopen převzít.

dustin

Re:Jak můžu opustit funkci
« Odpověď #67 kdy: 13. 07. 2018, 22:46:16 »
Tou korektností určitě nemyslel správnou funkcionalitu, ale "korektní čistotu" kódu.

balki

Re:Jak můžu opustit funkci
« Odpověď #68 kdy: 13. 07. 2018, 23:00:07 »
Skor je to problem, ze pisem aplikacie v ktorych klienti uprednostnuju robustnost pred korektnostou a musia sa spamatat za kazdej situacie. 
Nedá mi to, abych znovu nevytáhl výrok, který zapadl a přitom aspiruje na výrok roku v tomto fóru.

NIKDO, opravdu NIKDO, nemůže upřednostňovat robustnost před správnou funkčnosti. Jedinou výjimkou by za určitých podmínek mohla být armáda, ale ani tam si to nikdo nedovolí. Až ta vaše mašina někoho zabije nebo se zničí, tak budete těžko vysvětlovat, že jste jen splnil zadání. Mimochodem, napsat robustní program je triviální, problém trochu je, že nic nedělá.

A na závěr, pokud je vašim cílem vysoká robustnost, vybral jste si špatný jazyk, C rozhodně robustní není. Ale už vám do toho nebudu mluvit, znám takové týpky, 15 let oprašuje svoje zlaté tele, zpravidla jsou to samouci, co znají ve svém kódu každý řádek, ale jinak jsou nepoužitelní. Jejich zákazníci se každý den modlí, aby je náhodou nesrazilo auto, protože to nikdo jiný není schopen převzít.

Ok, vy si kodte taky softver, co vam nespracuje vstup na vystup, lebo vam sa nepaci. Ked sa vstup ale uctuje, tak sa nemoze vyparit. Musi sa oznacit patricne spracovat, opravit a oznacit ako chybny pre dalsie pouzitie. Ono, ked sa spracuva kvantum dat realtime a ide zo modulu A do modulu B cez ine moduly, tak sa asi zakaznik spyta, ze kam mu nieco zmizlo, nie?

Ad ta narazka z oprasovanim 15 rocneho systemu, vy budete nejaky fluktuant, co nieco spravi a ide o dum dal, a ini opravuju potom tu katastrofu, ze ? ;) Nie som samouk.

balki

Re:Jak můžu opustit funkci
« Odpověď #69 kdy: 13. 07. 2018, 23:10:16 »
Tou korektností určitě nemyslel správnou funkcionalitu, ale "korektní čistotu" kódu.

Tou korektnostou myslim to, ze program nespracuva zle vstupy, ale proste ich zahodi. (pripadne sa zjebe pri zlych vstupoch, to je ten horsi pripad)

Kit

Re:Jak můžu opustit funkci
« Odpověď #70 kdy: 13. 07. 2018, 23:19:15 »
Ok, vy si kodte taky softver, co vam nespracuje vstup na vystup, lebo vam sa nepaci. Ked sa vstup ale uctuje, tak sa nemoze vyparit. Musi sa oznacit patricne spracovat, opravit a oznacit ako chybny pre dalsie pouzitie. Ono, ked sa spracuva kvantum dat realtime a ide zo modulu A do modulu B cez ine moduly, tak sa asi zakaznik spyta, ze kam mu nieco zmizlo, nie?

Účetnictví není moc realtime, tam se prodlevy do několika sekund snesou. Pokud se něco nepovede, je potřeba vyhodit a zalogovat výjimku. V C to moc nejde a tak se na to vymýšlí různé berličky, i když jsou vcelku zbytečné.

balki

Re:Jak můžu opustit funkci
« Odpověď #71 kdy: 13. 07. 2018, 23:35:18 »
Ok, vy si kodte taky softver, co vam nespracuje vstup na vystup, lebo vam sa nepaci. Ked sa vstup ale uctuje, tak sa nemoze vyparit. Musi sa oznacit patricne spracovat, opravit a oznacit ako chybny pre dalsie pouzitie. Ono, ked sa spracuva kvantum dat realtime a ide zo modulu A do modulu B cez ine moduly, tak sa asi zakaznik spyta, ze kam mu nieco zmizlo, nie?

Účetnictví není moc realtime, tam se prodlevy do několika sekund snesou. Pokud se něco nepovede, je potřeba vyhodit a zalogovat výjimku. V C to moc nejde a tak se na to vymýšlí různé berličky, i když jsou vcelku zbytečné.

To nie je uctovnictvo.

Kit

Re:Jak můžu opustit funkci
« Odpověď #72 kdy: 13. 07. 2018, 23:42:00 »
Ok, vy si kodte taky softver, co vam nespracuje vstup na vystup, lebo vam sa nepaci. Ked sa vstup ale uctuje, tak sa nemoze vyparit. Musi sa oznacit patricne spracovat, opravit a oznacit ako chybny pre dalsie pouzitie. Ono, ked sa spracuva kvantum dat realtime a ide zo modulu A do modulu B cez ine moduly, tak sa asi zakaznik spyta, ze kam mu nieco zmizlo, nie?

Účetnictví není moc realtime, tam se prodlevy do několika sekund snesou. Pokud se něco nepovede, je potřeba vyhodit a zalogovat výjimku. V C to moc nejde a tak se na to vymýšlí různé berličky, i když jsou vcelku zbytečné.

To nie je uctovnictvo.

Viděl jsem jednu skutečně realtime aplikaci v C, která ze země řídí přistání letadel pomocí radarů a dalších senzorů. Pokud nejde o život, jde o ho*no. Před touto aplikací však mám respekt.

balki

Re:Jak můžu opustit funkci
« Odpověď #73 kdy: 13. 07. 2018, 23:57:30 »
Ok, vy si kodte taky softver, co vam nespracuje vstup na vystup, lebo vam sa nepaci. Ked sa vstup ale uctuje, tak sa nemoze vyparit. Musi sa oznacit patricne spracovat, opravit a oznacit ako chybny pre dalsie pouzitie. Ono, ked sa spracuva kvantum dat realtime a ide zo modulu A do modulu B cez ine moduly, tak sa asi zakaznik spyta, ze kam mu nieco zmizlo, nie?

Účetnictví není moc realtime, tam se prodlevy do několika sekund snesou. Pokud se něco nepovede, je potřeba vyhodit a zalogovat výjimku. V C to moc nejde a tak se na to vymýšlí různé berličky, i když jsou vcelku zbytečné.

To nie je uctovnictvo.

Viděl jsem jednu skutečně realtime aplikaci v C, která ze země řídí přistání letadel pomocí radarů a dalších senzorů. Pokud nejde o život, jde o ho*no. Před touto aplikací však mám respekt.

Take nieco by som si netrufol.  Alebo obsluha tazkych robotov, zdravotnicke zariadenia, jadrove elektrarne, tovarne. Kod z takych miest pre svoj klud radsej nechcem vidiet :)  Tipujem, ze sa tam programuje spajanim certifikovanych ciernych krabiciek (myslim modulov) :) A v tych certifikovanych moduloch nastane chyba max raz za 5 rokov a protichemicka jednotka to vycisti :)

x14

  • ***
  • 182
    • Zobrazit profil
    • E-mail
Re:Jak můžu opustit funkci
« Odpověď #74 kdy: 14. 07. 2018, 00:08:26 »
Tou korektnostou myslim to, ze program nespracuva zle vstupy, ale proste ich zahodi. (pripadne sa zjebe pri zlych vstupoch, to je ten horsi pripad)
Znělo to tak honosně a přitom jde jen o část zadání úlohy. Ovšem pokud je to postaveno vedle robustnosti programu (která je pro slušný program bezpodmínečná), tak je jasné, jak autor myslel "veci ako break, continue, goto by sa mali pouzivat v stave najhorsej nudze".