• úvod
  • témata
  • události
  • tržiště
  • diskuze
  • nástěnka
  • přihlásit
    registrace
    ztracené heslo?
    XCHAOSANSI C/C99 (specifikace), GNU C (gcc, glibc), Tiny C (tcc) a POSIX - ne nutně C++,g++,libstdc++ nebo Win32 API
    REDGUY
    REDGUY --- ---
    XCHAOS: jednoduše udělám jako "manuál" velkou tabulku všech svých maker, u kterých bude zmíněná jejich "kompatibilita" s break, continue, goto a return - takze soucasti jednoducheho, rychleho nastroje pro mikroprojekty urceneho pro zacatecniky (chapu to spravne?) bude velka tabulka ad-hoc nekompatibilit s normalnim C, kterou bude potreba se ridit protoze jinak se to rozbije? To ti prijde jako zjednoduseni? Co presne je podle tebe prinosem?
    XCHAOS
    XCHAOS --- ---
    REDGUY: když "víš co děláš", ano... ale ty prostě vycházíš z toho, že lidé co žádný toolkit nepoužití, _vždycky_ "vědí co dělají" - zatímco lidé, co ho použijí, _nikdy_ nevědí, co dělají.

    to ovšem není tak docela pravda - stejně jako můžeš zdokumentovat, že u open() je chybový kód filedescriptor<0 , zatímco u fopen() je to FILE==NULL, a lidi se to musí naučit, tak stejně tak programátoři v C<<1 si budou muset v dokumentaci přečíst, že místo break můžou univerzálně používat makro escape (v případech nespecializovaných smyček to udělá prostě break a basta). ano... je to pak prostě už "trochu jiný jazyk", stejně jako ObjectiveC je jiné, stejně jako C++ je jiné...
    XCHAOS
    XCHAOS --- ---
    REDGUY: tak zrovna to for_each() se chová slušně korektně pro continue; ... horší je to s break.

    uznávám, že např. nezavřený soubor při break; je nedomyšlenost (i když podle mě nikoliv neřešitelná). (ne všechny moje iterátory ovšem otevírají nějaký soubor...). tady by asi bylo nutné nějaké "escape", které by dělalo "přesně tu správnou věc" pro každé iterační makro.

    jednoduše udělám jako "manuál" velkou tabulku všech svých maker, u kterých bude zmíněná jejich "kompatibilita" s break, continue, goto a return. Nekompatibilitu s break (a v jistém smyslu s goto/return) bude nutné řešit makrem "escape", které bude něco jako "korektní break".

    jako programátor v Céčku jsem strávil mládí řešením, jak správně přečíst a pak zase zapsat textovej soubor s přesně správným počtem prázdných řádků na konci (typicky jeden nebo žádný). sice to je zajímavé intelektuální cvičení pro začátečníky - ale dost nesouhlasím s tím, že by toto nutně museli všichni znova podstupovat od začátku, a že by na to nešlo napsat nějaké triviální univerzální řešení po vzoru vyšších jazyků... ano, dost velký opruz zůstane hlídání vyjímek, alokací paměti, apod. - už skrze to to nikdy nebude "vyšší" jazyk... samozřejmě.
    REDGUY
    REDGUY --- ---
    XCHAOS: takhle, snad jsme se shodli, že možnost nevhodného použití returnu lidmi, co nevědí co dělají, je obecně VLASTNOST všeho v čistém C - je to chyba koncepce toho jazyka, resp. já to už nijak výrazněji nezhoršuji proti stavu, který je i beze mě. - boha jeho, to je neuveritelny. Tak jeste jednou a pomalu: kdyz vim co delam, _muzu_ return pouziv v C uprostred funkce bez problemu. I kdyz vim co delam, v Cll1 ho tak pouzit _nemuzu_. To je vyrazne _zhorseni_ stavu, _prosim_, prestan uz s timhle blabolem ze "nic nezhorsujes".
    REDGUY
    REDGUY --- ---
    XCHAOS: for_each & spol jsou nejmensim problemem. I kdyz samozrejme predstava ze bych musel nekdy hledat je chyba v #define for_each(ONE_T,ONE,ALL_T,...) for(_init_##ONE_T##_##ALL_T(_head_##ONE_T##_##ALL_T(ONE,__VA_ARGS__));_test_##ONE_T##_##ALL_T(ONE,__VA_ARGS__) || _free_##ONE_T##_##ALL_T(ONE,__VA_ARGS__);_next_##ONE_T##_##ALL_T(ONE,__VA_ARGS__)) je fyzicky bolestiva.

    Kde to zoufale nefunguje je tvoje snaha vytvaret nove struktury v C, ktere proste nejde trivialne namapovat na nejaky for/while. Viz rozbitej return/goto/break/continue, to vsechno kvuli jen napul fungujicim "kontextum".
    XCHAOS
    XCHAOS --- ---
    JACHYMKO: takhle, snad jsme se shodli, že možnost nevhodného použití returnu lidmi, co nevědí co dělají, je obecně VLASTNOST všeho v čistém C - je to chyba koncepce toho jazyka, resp. já to už nijak výrazněji nezhoršuji proti stavu, který je i beze mě.

    ano, tak trochu mám pocit, že pokud by člověk psal opravdu čistě strukturovaný kód, s využitím systému odchytávání vyjímek, tak asi nebude mít až tolik případů, kdy by měl z jedné funkce více returnů:

    1) obecně, pokud je to void funkce a nevrací žádnou hodnotu, tak jí lze nejspíš rozdělit na více dílčích funkcí

    2) ad příklad s tou deinicializací - ona správná odpověď asi je, že toto by se napsalo "C-objektově" - tedy všechny ty lokální proměnné by byly ve struct, a ten de-inicializátor by byla funkce, které se předává pointer na struct a kterou lze zavolat z více míst...

    2) pokud funkce vrací nějaký výsledek, tak skutečně její vnitřní větvení, ukončené různými návratovými hodnotami - včetně nastavení hodnot indikujících chybu, apod. - by se mohla "sbíhat" před místem, kde se vrací ta návratová hodnota. opravdu jsem takto viděl jiné lidi programovat a nemyslím, že je to špatný přístup.
    XCHAOS
    XCHAOS --- ---
    REDGUY: no, v době mých prvních pokusů jsem je skutečně používal špatně - resp. vygeneroval jsem hrozné množství maker, a chtěl jsem dělat jejich speciální verzi pro každý myslitelný datový typ, apod. ... skutečně jsem i sám sebe poměrně rychle přesvědčil, že směřuju do slepé uličky.

    vezmi si ale, že třeba standardizované operace va_start(), va_arg() a va_end() jsou taky většinou (plaform-dependend) implementované jako makra, která jsou VELICE podobná přístupu, který razím já.

    a teď si představ, že bych udělal for_each(int, .., args, ...) {}, for_each(str, ..., args ...) {} ... které by šlo použít u funkcí s proměnným počtem argumentů - ale bylo by to celé daleko čistší ?

    a pokud to moje 4+ argumentové for_each() bude skutečně univerzální pro celou řadu iterací, které jsou v C tak nějak "nakousnuté", ale vlastně se pokaždé dělají jinak ?
    REDGUY
    REDGUY --- ---
    Hele, XChaosi, fakt bych moc rad abys mi odpovedel na tohle, pro jistotu to prikopiruju sem:

    začátečník, kterého budeš učit céčko ty, každopádně nabude dojmu, že z C funkce je možné kdykoliv bez rozmyšlení utéct - nikolvek. Zacatecnik, ktereho budu ucit programovat, se nauci tohle:

    * Pamet se alokuje pomoci malloc
    * Kazdou alokovanou pamet musis uvolnit pomoci free

    Co se musi naucit zacatecnik pouzivajici tvuj alokator?

    * V nekterych pripadech se pamet alokuje pomoci xchaos_alloc, v ostatnich pripadech pomoci malloc. Pravidlo pro rozliseni techto pripadu je "..." (zhruba odstavec textu).
    * Pamet alokovana pomoci malloc se musi uvolnit pomoci free.
    * Pamet alokovana pomoci xchaos_alloc se uvolnovat nemusi.
    * Pred tim nez pouzijes xchaos_alloc musis spravne clenit kod na forget/remember bloky
    * Pokud jsi cetl nejakou knihu o C, tak zapomen na prikaz return jinde nez na konci funkce.
    * Pokud jsi cetl nejakou knihu o normalnim C, nezapomen ze break/continue se v nekterych pripadech chovaji jinak nez bys cekal.
    * goto a setjmp/longjmp is right out.

    Zapomel jsem na neco? Co ti prijde jednodussi?
    XCHAOS
    XCHAOS --- ---
    JACHYMKO: asi taková, jako že tebe "donutím" začít vyvíjet céčkové aplikace pro Linux, místo pro mikrosoftí platformy ?
    REDGUY
    REDGUY --- ---
    XCHAOS: vidím, že si konečně vzal na milost makra Ach jo. Psal jsem nekdy ze obecne pouzivat makra je spatne? Nepsal. Psal jsem, ze spatne je zpusob jakym je pouzivas ty.

    že si uvědomuješ závažnost problému s random-return z plain-C funkce - dtto. Ano, je potreba uvolnovat zabrane zdroje. V C to jde (kdyz na to clovek mysli) i pri pouzit returnu uprostred funkce, v tvem bastlu return uprosted pouzit nemuzes vubec.

    velká spousta programátorů tento problém řeší tím, že k úniku z funkce používá místo tebou navrhovaných maker např.nějaké goto na deinicializační blok.... fakt jsem to takto viděl už mnohokrát. - LOL. Jeste nedavno jsi psal, ze, cituji "v C [se] doporučuje použít goto max. jen na ošetření chyb (s následným rychlým ukončením programu, pokud možno)". Tak jak to je? Prosim, pokud uz si s prstu cucas ucelove argumenty podle toho co zrovna potrebujes, _prosim_, aspon si je pamatuj a bud konzistetni. A btw, samozrejme ze pouziti goto tak jak ho tady popisujes problem tvych "kontextu" neresi, protoze je rozbije uplne stejne jako return.

    Nicmene, psal jsi neco o milionu zpusoby kdy i v normalnim C nelze pouzit return uprostred funkce. U jednoho jsem ti ukazal jak na to, takze bych prosil nejaky dalsi z tech zbylych 999 999?
    XCHAOS
    XCHAOS --- ---
    REDGUY: ad "lepší C" - uvažoval jsem jít na to inkrementálně:

    C<<1 by byla sada maker a funkcí, kterou vyvíjím teď
    C<<2 by byl pre-compiler, který by konvertoval nějakou elegantní obejktovou syntaxi na volání metod z interfaců přiřazených strukturám, případně by hlídal dědění, správu paměti, volání destruktorů nakonci scope, apod. (něco jako Objektive C).

    výhoda by bylo, že oboje dvoje by byla jen nadstavba využívající existující compilery a knihovny: jsem popravdě líný, a tu "skutečnou" práci spojenou s vývojem nějakého kompileru se mi dělat nechce...
    XCHAOS
    XCHAOS --- ---
    REDGUY: ano, děkuji, že si konečně pochopil, že je to koníček. a že nemusíš na každý můj příspěvek nutně reagovat :-)

    kromě toho si všimni, že já jsem opustil myšlenku toho mít to postavené čistě jen nad preprocesorem už dost dávno: nyní můj header obsahuje cosi jako mikro-knihovnu (tedy makro "program" implementuje potřebné funkce".

    je to určené vysloveně pro mikro-projekty, a víceméně se ani nepředpokládá použití spolu s Makefily - používá se nějaký "quick and dirty" přístup k vývoji prográmků a použití mého jednoduchého kompilačního skriptu "bake". je to prostě hračka pro lidi, co mají pocit, že "méně je někdy více" - něco jako elektrokolo, moped, ultralehké letadlo, motorový paraglide... (výrobci dopravních letadel a autobusů můžou být v klidu :-)
    XCHAOS
    XCHAOS --- ---
    JACHYMKO: kdybych tyto problémy neřešil v C, tak nejspíš nikdy nepochopím, který typ problémů vlastně C++ řeší za mě. (a kromě toho - C++ je neřeší zdaleka tak automaticky, jako skutečné vyšší programovací jazyky...)
    XCHAOS
    XCHAOS --- ---
    REDGUY: zajímavé... vidím, že si konečně vzal na milost makra :-) a že si uvědomuješ závažnost problému s random-return z plain-C funkce :-)

    každopádně, to co navrhuješ je sice pěkné - ale opravdu, velká spousta programátorů tento problém řeší tím, že k úniku z funkce používá místo tebou navrhovaných maker např.nějaké goto na deinicializační blok.... fakt jsem to takto viděl už mnohokrát.

    ISTEVE: ve skutečnosti: to samé, co budu volat "zevnitř" makra
    forget { }, můžu samozřejmě volat i z nějakého makra dejme tomu "escape" - to provede něco jako { forget_close(); return; }.

    ve skutečnosti - pro různá svoje makra můžu udělat nějaký speciální indikátor, jaký typ destruktoru má volat makro "escape" - např. for_each() flow control makro by nařídilo, aby escape uzavřelo soubory - a asi by to šlo i vnořovat: tedy, pro všechna moje flow control makra která na začátku něco inicalizují a na konci deincializují, by escape mohlo být "bezpečnou" verzí returnu (a pokud bys použil escape mimo scope, tak by prostě udělal return)

    nicméně je to překombinované, a já radši ve svém dialektu udělám méně maker a lépe zdokumentuji, co přesně dělají... než abych vymýšlel další takovéhle berličky.
    REDGUY
    REDGUY --- ---
    JACHYMKO: Coz o to, ja chapu proc se o to snazi, i kdyz ze vsech praktickejch hledisek je to, v dobe existence C++, Javy, ObjC, Scaly a ja nevim ceho jeste, zcela zbytecne. Proste je to konicek, hobby projekt kterej si clovek vymysli a dotahne od zacatku do konce. To naprosto chapu, preju mu to a obdivuju ho za vytrvalost jakou se ho drzi.

    Co ale nechapu je, ze po vsech tech letech co mu tady rikame ze C preprocesor fakt neni vhodnej nastroj na tenhle projekt tak se ho porad drzi. (A nejen ze mu to rikame, ale i prakticky ukazujeme na ruznych zpusobech, jakym je to konkretne rozbite). To neni obdivuhodna vytrvalost ale neco, co radsi nebudu pojmenovat aby tenhle prispevek pusobil aspon trochu konstruktivne 8)


    XChaosi, C preprocesor slepa ulicka. Krome myriad postranich problemu ma hlavni problem v tom, ze nevi a nemuze vedet nic o strukture C programu. Jak v obecne rovine, kdy proste nema prostredky popsat syntaxi C, tak konkretne, ze nevi v jake casti kodu se to ktere makro zrovna expanduje. A kdyz nic nevi o strukture, nemuze ji ani efektivne modifikovat.

    Jestli chces opravdu udelat "Lepsi C", pouzij na to spravny nastroj. Jestli chces hardcore klasiku, lex/yacc (resp. flex/bison), z modernejsich treba Antlr. Pro oboje existuji C gramatiky, ktere muzes vzit jako zaklad a nad nima postavit poradny preprocesor ktery Cll1 prelozi do C. Drzet se za kazdou cenu nastroje, ktery je tak extremne nevhodny jako CPP, je jen a jen plytvani casem ktere nikam nepovede.
    ISTEVE
    ISTEVE --- ---
    Ja mam hrozne bolestnej pocit, ze xchaose by uspokojilo kdyz by mel scoped objekty (s moznosti definice destruktoru) v C, a toho cile se snazi dosahnout preprocessor makrama.
    ISTEVE
    ISTEVE --- ---
    XCHAOS: A stale se nemuzu ubranit argumentaci lidskou masou -- programovaci jazyky jsou pro konzumaci programatory, mas jedinyho kterej by tohle povazoval za dobrej napad? Ja vidim spoustu lidi, co to za dobrej napad nepovazuje, a i kdyz budes reagovat ze se jen hadaj, tak ti to furt lidi co souhlasej nenajde...
    DAVIDOWITCH
    DAVIDOWITCH --- ---
    Auto Release Pool in Pure C Language - CodeProject
    http://www.codeproject.com/KB/cpp/memreleasepool.aspx
    (pozor, pouziva manualni refcounty, ale vesmes to sedi na forget blok)

    A ve zkracene verzi (bez obrazku): http://en.wikipedia.org/wiki/Leaky_abstraction
    ci prodlouzene (i s obrazky): http://www.joelonsoftware.com/articles/LeakyAbstractions.html
    vrele doporucuji precist vsem tem co to necetli
    ISTEVE
    ISTEVE --- ---
    XCHAOS: S tvoji vymyslenosti jsou dve varianty:
    a) Nemuzu udelat manualni release pameti, a tudiz nemuzu pouzit return v polovine funkce.
    b) Muzu udelat manualni release pameti, a tudiz je mi tvoje vymyslenost na hovno.
    _BENNY
    _BENNY --- ---
    DAVIDOWITCH: ano

    1) u matematickych funkci nad maticemi to asi pujde dobre rozdelit do funkci s nejvyse tremi/ctyrmi parametry, casto casem zjistis ze potrebujes delat i nejake dilci operace, takze funkce/makro volajici/pouzivajici dalsi funkci/makro je imho ok, alespon ja to tak mam rad :)

    2) obvykle resim zkracovanim vseho do jedineho vyrazu/prirazeni, doufaje ze tim nejak usnadnim kompilatoru praci, ale asi je to v dnesni dobe vyspelejsich kompilatoru uz zbytecne. const nepouzivam, kdyz je potreba, prepisu kriticky kod do asm (vim, jebacka s portabilitou :)
    Kliknutím sem můžete změnit nastavení reklam