Intel vydal 34 upozornění na bezpečnostní chyby ve svých produktech. Současně vydal verzi 20250211 mikrokódů pro své procesory řešící 5 bezpečnostních chyb.
Byla vydána nová verze 1.24 programovacího jazyka Go (Wikipedie). Přehled novinek v poznámkách k vydání.
Jiří Eischmann upozorňuje, že GNOME nemá české překladatele: "Posledních minimálně 15 let byly překlady GNOME do češtiny ve výborném stavu. U každého vydání jsem jen hlásil, že je vše přeložené, poslední roky to platilo i pro drtivou většinu dokumentace. Poslední rok se to ale začalo zadrhávat. Přispěvatelé, kteří to dlouhé roky táhli, odešli a není nikdo, kdo by to po nich převzal. Proto jsme se rozhodli jít s pravdou ven: GNOME momentálně nemá české překladatele a pokud se toho neujme někdo nový, překlady začnou postupně upadat."
Otevřený zvukový bezztrátový kodek FLAC (Free Lossless Audio Codec, Wikipedie) byl vydán v nové verzi 1.5.0. Hlavní novinkou je podpora vícevláknového kódování. V prosinci loňského roku byl FLAC formálně specifikován v RFC 9639.
Evropská unie hodlá iniciovat investice do rozvoje umělé inteligence v hodnotě 200 miliard eur, v přepočtu zhruba pět bilionů korun. V projevu na summitu o umělé inteligenci v Paříži to v úterý řekla předsedkyně Evropské komise Ursula von der Leyenová. Umělá inteligence podle ní může přispět mimo jiné ke zvýšení konkurenceschopnosti.
Desktopové prostředí KDE Plasma bylo vydáno ve verzi 6.3 (Mastodon). Přehled novinek i s videi a se snímky obrazovky v oficiálním oznámení. Podrobný přehled v seznamu změn.
Lennart Poettering se na Mastodonu rozepsal o novince v systemd, na které pracuje: systemd bude umět nabootovat z obrazu disku staženého pomocí HTTP v rámci initrd.
Open source platforma Home Assistant (Demo, GitHub, Wikipedie) pro monitorování a řízení inteligentní domácnosti byla vydána ve verzi 2025.2. Nově lze zálohovat také na Google Drive a Microsoft OneDrive.
V kinech aktuálně běží animovaný film Kočičí odysea, v originálu Flow, (Wikipedie) vytvořený v Blenderu. Film získal řadu ocenění a má dvě nominace na Oscary 2025. Na ČSFD má 80 %. Režisérem je Gints Zilbalodis. Rozhovor s režisérem na stránkách Blenderu.
Oficiálně byla vydána (Mastodon, 𝕏) třetí RC verze GIMPu 3.0. Přehled novinek v oznámení o vydání. Podrobně v souboru NEWS na GitLabu. GIMP je nově k dispozici také ve formátu AppImage.
if(!ob_start("ob_gzhandler")) ob_start();mám to brát jako že to autor myslel takto?
if(!ob_start("ob_gzhandler")) { ob_start(); }else{ ob_start("ob_gzhandler"); }Že již při testováni ob_start("ob_gzhandler") se ta funkce zavolá proto nepoužil else? Díky
Řešení dotazu:
else
tam máš navíc. Ten druhý příklad by nefungoval správně.
ob_start() je funkce, která jako výsledek obsahuje hodnotu, zda se povedla či ne. Tuto hodnotu můžeš testovat.
ob_start("ob_gzhandler") || ob_start();
if(!ob_start("ob_gzhandler")) ob_start();
Člověku, který je ve svém kódu zvyklý takové obraty rutinně používat, to tak možná nepřijde, ale pro ostatní to výrazně snižuje čitelnost a srozumitelnost kódu.
Jinak většina přísnějších coding styles by nepovolila ani tu alternativu, kterou jste uvedl (a muselo by se to rozdělit na dva řádky).
ale když už, tak z těchto dvou možností mi přijde hezčí ta s ||.+1
do_somethig() or do_something_else()nebo
try do_something() except do_something_else()kdyz uz podminku tak
if is_supported_feature() do_something() else do_something_else()v podminenem vyrazu proste cekam predikat
udělejNěco() || udělejNěcoJiného()
krásně čitelné a na první pohled srozumitelné. Ještě lepší jsou ty výjimky, ale když už nejsou k dispozici, tak bych si alespoň výsledek první akce přiřadil do proměnné (s rozumným názvem) a tu vyhodnotil v podmínce na samostatném řádku.
OMG, to je zase flame Už na začátku jsem psal, že se mi moc nelíbí ani jedno. Moje pořadí:
V případě nějakých skriptů nebo jazyků, kde je zvykem tak psát, bych 3 posunul na druhé – možná i první, pokud nejsou podporované výjimky – místo. Možnost 4 mi přijde ze všech nejošklivější a nejméně čitelná.
Snad jen že jsem moc rád, že většina projektů, do kterých přispívám a s jejichž kódem musím pracovat, na to má opačný názor než vy dva.Ve Frantově případě už opravdu jen trolluješ, vzhledem k tomu, že opačný názor k jeho je v podstatě použít libovolnou z možností, které se mu nelíbí.
||
neospravedlnitelná prasárna, pro něj je to naprosto přirozená konstrukce. Pro mne je naprosto v pořádku použít funkci s vedlejším efektem v podmínce, pro něj je to neospravedlnitelná prasárna. Takže v tom se prostě shodnout nemůžeme.
pro něj je to naprosto přirozená konstrukceVětšinou píšu v Javě a tam to nepoužívám. Občas v Perlu nebo Bashi ano a tam mi to přijde jako lepší varianta.
…použít funkci s vedlejším efektem v podmínce, pro něj je to neospravedlnitelná prasárna.Abych to trochu zmírnil: nepovažuji to za úplné tabu, ale přijde mi to horší než použití ||. Když kouknu letmo na zdroják, tak vidím posloupnost příkazů a bloky, které se provádějí jen někdy, za určitých okolností – ale že se v závorce za IFem bude ukrývat i nějaký výkonný kód a ne jen vyhodnocení těch okolností, považuji za trochu zákeřné – je potřeba číst pozorněji a není to takové rychlé „kouknu a vidím“ – což zrovna u toho || funguje (pokud někdo nepíše kilometr dlouhé řádky, ale to je zase jiná kapitola). Chápu, jak to myslíš, a i že je to trochu zneužití téhle konstrukce… Ale když se podívám na výsledek, je to pro mne čitelnější než if + negace + pár závorek (a to jsem jinak docela fanda do závorek a píšu je rád). Že se výsledná hodnota nikam nepřiřadí nebo nepoužije taky není takový hřích – celkem často se volají nějaké metody/funkce, které něco vrací a výsledek nepotřebuješ, tak s ním dál nepracuješ.
P.S. dávat do podmínky výraz, který něco dělá/mění (místo aby jen zjišťoval) mi přijde fakt prasárna
if not decrypt(file, candidate): do_some_cracking()
if not kytička = tsql.fetchone(): log("Strange, gardener solved job I did not submit!", LOG_ERR) return zasaď(kytička)Přesvědčuj, ještě to můžu změnit! :)
if
), vždyť to už hraničí i s klasickým
if((fw=fopen("xy", "wb") != NULL){ if((fwrite( buff, sizeof(char), n, fw)) != n){ //write error } if(fclose(fw) != 0){ //write/close error } }else{ //open error }ten kód je, tedy podle mě, čitelný a hezký.
Také si myslím, že umělé ukládání návratové hodnoty do proměnné, pokud se pak k ničemu jinému nepoužije, přehlednosti nijak neprospívá, spíš naopak. Něco jiného už je samozřejmě situace, kdy hodnotu tak jako tak musím uložit, např.
if ((buffer = malloc(n * sizeof(int))) == NULL) { ... } ...
Tam bych se naopak přiklonil k rozdělení.
if((fw=fopen("xy", "wb") != NULL){tak i
if((buffer = malloc(n * sizeof(int))) != NULL){mi přijde dobré v případě, že v bloku na základě té podmínky pracuji s danou návratovou hodnotou. Proto jsem to vyhodnocení úspěšnosti alokace otočil. Ale i následující mi přijde jako OK:
if((buffer = malloc(n * sizeof(int))) == NULL){ //error & exit }A naopak u všech to cítím tak, že když se to vyhodí z podmínky tak to zhoršuje čitelnost, ale hlavně zvyšuje riziko vložení kódu „mezi“.
lock()
jsem se v příkladu vykašlal…):
while(!allDataProcessed()){ if(((buffer = getBuffer()) != NULL) //get a free buffer &&(readData(&buffer))){ //read data into the buffer //process buffer… releaseBuffer(&buffer); }else{ pthread_cond_wait(&cond, &mut); //wait for release a buffer or reading thread } }Ale věřím, že spoustě lidí se to nelíbí…
lze v jedné podmínce provést dva příkazy, přičemž druhý se neprovádí v případě…Takže k tomu IFu přidáš ještě konstrukci typu:
ob_start("ob_gzhandler") || ob_start();
aaa() || bbb();čitelné, ale když se to začne ztrácet v IFu a negacích, už je to horší – je těžší tam na první pohled vidět ty metody, které něco dělají/mění…
OR
a takovéhoto použití mi přijde zbytečně brainfuck-ové.try fw = fopen() fwrite(fw) fclose(fw) except print errornebo toto
( fw = fopen() and fwrite(fw) and fclose(fw) ) or ( die() )samozrejme se nebavime o C, ktery tyto konstrukce neumi.
die()
je die, tak jen nedokonalý.fwrite()
, a „print error“ naznačuje že soubor zůstane otevřený kdoví do kdy.
Myslel jsem, že svůj názor na použití logických operátorů coby maskovaných podmíněných příkazů jsem už sdělil dostatečně zřetelně… Co se výjimek týká, tak pokud je jazyk má, je to fajn, ale ani v tom případě se nehodí vždy. Třeba když budu chtít pomocí výjimek přepsat kód typu
int __init ip6_route_init(void) { int ret; ret = -ENOMEM; ip6_dst_ops_template.kmem_cachep = kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, SLAB_HWCACHE_ALIGN, NULL); if (!ip6_dst_ops_template.kmem_cachep) goto out; ret = dst_entries_init(&ip6_dst_blackhole_ops); if (ret) goto out_kmem_cache; ret = register_pernet_subsys(&ipv6_inetpeer_ops); if (ret) goto out_dst_entries; ret = register_pernet_subsys(&ip6_route_net_ops); if (ret) goto out_register_inetpeer; ... ret = fib6_init(); if (ret) goto out_register_subsys; ret = xfrm6_init(); if (ret) goto out_fib6_init; ret = fib6_rules_init(); if (ret) goto xfrm6_init; ret = register_pernet_subsys(&ip6_route_net_late_ops); if (ret) goto fib6_rules_init; ret = -ENOBUFS; if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) || __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) || __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL)) goto out_register_late_subsys; ret = register_netdevice_notifier(&ip6_route_dev_notifier); if (ret) goto out_register_late_subsys; ...
tak mi výjimky kód spíš znepřehlední.
ret
mi přijde lepší, než nacpat výkonný kód do závorek za IF. A to GOTO je vlastně taková emulace výjimek Použití proměnné ret mi přijde lepší, než nacpat výkonný kód do závorek za IF.
Kdybych tu funkci zkopíroval celou, bylo by vidět, že ukládání návratové hodnoty do proměnné ret
není samoúčelné, protože uložená hodnota se v případě chyby použije jako návratová hodnota ip6_route_init()
. Což se promítá i do téhle části:
ret = -ENOBUFS; if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) || __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) || __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL)) goto out_register_late_subsys;
která mimochodem dělá přesně to, co se vám nelíbí.
A to GOTO je vlastně taková emulace výjimek
Jenže v tomto případě by právě výjimky z hlediska přehlednosti nadělaly víc škody než užitku.
Což se promítá i do téhle části:÷Zrovna tady by se proměnná hodila – smyslem proměnné totiž není jen to, že v IFu nebude výkonný kód, ale i to, že si nějakým výstižným názvem pojmenuji výsledek logické operace složené z několika AND/OR – aby to člověk nemusel luštit vždy znovu a znovu a zkoumat, proč tam jsou zrovna takový ORy a ANDy a co tím chtěl původní autor říct.
Jenže v tomto případě by právě výjimky z hlediska přehlednosti nadělaly víc škody než užitku.Neznám kontext, může být.
aby to člověk nemusel luštit vždy znovu a znovu a zkoumat, proč tam jsou zrovna takový ORy a ANDy a co tím chtěl původní autor říct.Hlavně se obsah proměnné hezky zkoumá v debuggeru, takže pokud se nejedná o něco, o čem se předpokládá, že to nebudu nikdy potřebovat debugovat, tak to není špatný nápad. Optimalizovaná verze se stejně bez místa v paměti pro nepotřebnou lokální proměnnou obejde.
-O0
, tak ano.
Neznám kontext, může být.
Kontext je jednoduchý. Je třeba provést sérii asi tak deseti inicializací ve správném pořadí s tím, že pokud některá selže, všechno, co se dosud povedlo, se zase musí (v opačném pořadí) vrátit zpět. V C++ by se to nejspíš řešilo přes nějakou umělou třídu a pomocné třídy pro jednotlivé kroky inicializace, ale to zase zanáší nežádoucí overhead.
public void nějakáMetoda() { try { vytvořitSpojení(); připravitSQLDotaz(); vykonatSQLDotaz(); } catch (Exception e) { zavřít(spojení, dotaz, výsledkováSada); } } public static void zavřít(Connection spojení, Statement dotaz, ResultSet výsledkováSada) { if (výsledkováSada != null) { try { výsledkováSada.close(); } catch (Exception e) { // nedá se už nic dělat, jen zalogujeme } } if (dotaz != null) { try { dotaz.close(); } catch (Exception e) { // nedá se už nic dělat, jen zalogujeme } } if (spojení != null) { try { spojení.close(); } catch (Exception e) { // nedá se už nic dělat, jen zalogujeme } } }
A hlavně se ta byznys logika neztrácí mezi haldami pomocného, uklízecího a výjimky ošetřujícího kódu.Ztrácení užitečného kódu způsobují někdy i „korporátní“ konvence pro logování a jednotkové testování…
----------------------------------------------------------------- STATE | ACTION | OK | ERROR - 1 | ERROR - 2 | ...... ----------------------------------------------------------------- init | do_init() | inited | init | final inited| do_someting() | next | init | init final | exit() | null | null
while state != 'final' retval = execute(table[state][action]) state = table[state][retval]
definice tabulky: obycejne pole, list, dict, map ... - pametova narocnost pro desitky stavu je nulova
predavani parametru: trivialni - list, dict, map ...
wrappery nemusi bejt potreba, pripadne se muzou generovat automaticky.
Ihned utnu namitku, ze v C a v kernelu si nemuzeme dovolit nejake listy a mapy. Na par radku se da napsat generator, ktery tento automat prevede do C-kovyho kodu, i se vsema vyhodama, ktere nasleduji.
Co je ale obrovskej prinos? Verifikace a validace. Ten kod kernelu, co jste poslal, je vicimene nemozne poradne otestovat (ale co uz, mame tisice testeru, tak je nam to fuk :) ).
Definici stavoveho automatu muzeme krasne validovat oproti zadani. Jenoduchy provadeci kod automautu se poradne otestuje jednou a pak uz to mame zadarmo. Jednotlive akce pujdou krasne unit testovat.
definice tabulky: obycejne pole, list, dict, map ... - pametova narocnost pro desitky stavu je nulova
predavani parametru: trivialni - list, dict, map ...
wrappery nemusi bejt potreba, pripadne se muzou generovat automaticky
Zkuste si to pro ten konkrétní příklad. Uvidíte, že náročnost není ani zdaleka "nulová", že kódu bude ve výsledku podstatně víc než je ho teď a že se v něm bude podstatně hůř orientovat.
Na par radku se da napsat generator, ktery tento automat prevede do C-kovyho kodu, i se vsema vyhodama, ktere nasleduji.S tím souhlasím a myslím, že by to pomohlo mnoha programům – efektivita programu tím netrpí (generuje se ještě před kompilací), chybovost (překlepy atd.) je omezena, jsou lépe oddělena data od logiky, snáze se přidají nová data…
To tak trochu zavání 10. pravidlem, resp. zde nastává problém nutné znalosti generátoru k pochopení zdrojového kódu.Ihned utnu namitku, ze v C a v kernelu si nemuzeme dovolit nejake listy a mapy. Na par radku se da napsat generator, ktery tento automat prevede do C-kovyho kodu, i se vsema vyhodama, ktere nasleduji.
zacatecnikum kteri se prave dozvedeli o zkracenym vyhodnocovani to muze pripadat "Fujtajbl"...
Jsou takovéhle urážky nutné, zvlášť když dobře víte, jak moc jsou mimo mísu?
ob_start("ob_gzhandler") returns FALSE if browser doesn't support gzip, so then is called normal ob_start();Tzn. browser podporuje gzip, nastartuje se output buffering s callbackem ob_gzhandler. Pokud nepodporuje, spusti se standardni output buffering.
if (foo()) bar();je zkraceny zapis tohoto:
if (foo()) { bar(); }vhodny pokud v podminenem bloku je jen jeden prikaz; Jinak taky preferuju zapis, ktery ukazal mike
Že již při testovániob_start("ob_gzhandler")
se ta funkce zavolá proto nepoužilelse
?
Samozřejmě. Jak byste chtěl zjistit návratovou hodnotu funkce, aniž byste ji zavolal?
ok = ob_start("ob_gzhandler"); if (!ok) { ob_start(); }
Tiskni
Sdílej: