Mě také. Dlouho jsem neviděl žádný jazyk na který bych byl ochoten z C přejít, ale nyní musím uznat že C3 se hodně povedl. Navíc to že je s C binárně kompatibilní je killer-feature.
Chápu, to je vcelku dost příjemná vlastnost Zigu. V C3 to momentálně nejde a nejspíš ani nepůjde. Existuje nějaký generátor bindingů založený na libclang, ale není to zdaleka tak pohodlné jako v Zigu.
> Navíc to že je s C binárně kompatibilní je killer-feature.
Super je, že i třeba funkce vracející Optional jde volat z C nebo jiných jazyků - není potřeba žádná speciální konvence pro volání.
Jinak souhlasím, že se C3 povedl. Zůstal stále vcelku jednoduchý a podobný C. Výhoda obojího je, že kdyby se nedejbože C3 přestal vyvíjet (ať už úplně, nebo směrem, kterým chci), tak jde kód zase převést do C, případně kompilátor C3 trochu upravit ručně.
přitom hodně z těch změn (defer, ty "otaznikovy" proměnný s unwrapingem) by mohly jít přímo do C, protože nenaruší zpětnou kompatibilitu. Tak třeba C25 nebo C26 nebo tak to nakonec přidá :-)
Ono to ide trochu filozofii alebo hlavnej vyhode jazyka C - a to, ze sa deje len to co vidim v kode, proste ziadna magia.
Z popisu toho defer mi není jasné, jestli se odloží celý příkaz, nebo jestli se nejprve vyhodnotí třeba parametry "nejvnějšnější" funkce?
{ int a = 0; defer io::printf("%d", a); a++; defer io::printf("%d", a); } --> 1 1 ?
9. 10. 2025, 13:49 editováno autorem komentáře
defer, stejně jako třeba if může za sebou mít buď jeden příkaz nebo celý { blok; příkazů; }
K celému spuštění dojde až na konci scopu v kterém byl defer zaregistrován.
nic se nepředvyhodnocuje, lze si to představit jakoby defer vložil jeho kód do všech míst kde může končit scope.
Defer má stále přístup k lokálním proměnným, takže není žádný problém vyhodnotit vše na konci scopu.
Defer má stále přístup k lokálním proměnným, takže není žádný problém vyhodnotit vše na konci scopu.
Problém by to byl, když se hodnota té proměnné změní: volám-li defer třeba z cyklu, kde otevírám soubory a jejich deskriptor ukládám do stejné proměnné. Pro jsem se naivně ptal - trochu mne k tomu navedla zmínka, že defer používá zásobník...
Ale stačí vědět, že takhle se defer použít nedá a je to jednodušší, než přemýšlet, která část příkazu se vyhodnotí hned a která se odloží.
Tak běžně při první chybě lezu z funkce (nebo scopu) ven a tímpádem se hned zavolá defer kód, čili ke změně proměnných nedochází.
if(chyba)
return; // tady se mi zavolá defer kód
Účelem deferu je umožnit po sobě elegantně uklidit, bez duplikovaného kódu, bez možnosti vynechat (opomenout) nějaký třeba nově přidaný return.
Ještě jednodušší než přemýšlet která část příkazu se vyhodnotí hned a která se odloží je uvědomit si, že žádná se nevyhodnotí hned a vše se odloží - pak není nad čím přemýšlet :-)
Pokud bych však přesto všechno z nějakého důvodu potřeboval například vypsat hodnotu o které vím že před exitem scopu se ta hodnota změní, tak to taky není žádný problém. Mohu si při chybě alokovat paměť, do ní zapsat aktualní hodnotu nebo rovnou zformátovanou log message a v defer části ji vypsat a a uvolnit alokovanou paměť.
14. 10. 2025, 15:43 editováno autorem komentáře