Portál AbcLinuxu, 12. května 2025 14:40
Microsoft potvrdil portaci vybraných nástrojů z balíku Sysinternals na Linux. Na GitHubu jsou k dispozici zdrojové kódy nástroje ProcDump. Potvrzena je portace nástroje ProcMon [Slashdot].
Tiskni
Sdílej:
Debugování pod Windows funguje bezvadně … Stačí ve Visual Studiu zaškrtnout,…Víš, někteří lidé jsou zvyklí debugovat věci na konzoli, a bez klikátek, protože tam vidí co se děje, a výstup mohou si kupř. přesměrovat do souboru k podrobnějšímu prostudování.
Debugování pod Windows funguje bezvadně i bez nahrazování jakéhokoliv DLLka či kernelových modulů. Stačí ve Visual Studiu zaškrtnout, že má používat Mikrosoftí symbol servery. (U jiných debuggerů bývá obdobný přepínač.)A to řeší ten problém s absencí debug symbolů v non-debug knihovnách atd. slinkovaných oproti non-debug runtime? Pokud ano, otázka pak je, k čemu ten debug mód vůbec je...
Neexistuje, protože ve vší obecnosti to nelze. (Proces otevře soubor, odlinkuje ho ze souborového systému, pak si uživatel vzpomene, že chce začít sledovat. Navíc to komplikuje možnost duplikovat či posílat deskriptory cizím procesům).
Nicméně kanón na každou velikost ptáka se vždy najde. Obyčejné řešení je lsof -f -- CESTA_K_SOUBORU
. Výkonnější řešení v reálném čase je systemtapová sonda. A ultimátní řešení je používat jádro se zapnutým auditem a kýženou operaci dohledat v logu démona auditd.
Proces otevře soubor, odlinkuje ho ze souborového systému, pak si uživatel vzpomene, že chce začít sledovat.A kam ho odlinkuje? Mplayer otevře channel.conf a než ho začnu chtít sledovat tak fíí a je pryč?
Obyčejné řešení je lsof -f -- CESTA_K_SOUBORU. Výkonnější řešení v reálném čase je systemtapová sonda. A ultimátní řešení je používat jádro se zapnutým auditem a kýženou operaci dohledat v logu démona auditd.Ano, Správce procesů je linuxová parodie. Spíš je to jen zabíječ procesů krom pár drobnějších možností jako změna pririty. Ten Gnu/Linux moc průhledný není, že něco zapisuje na disk poznáte až je disk plný a nemůžete už zapisovat nic.
A kam ho odlinkuje? Mplayer otevře channel.conf a než ho začnu chtít sledovat tak fíí a je pryč?Třeba vmware esxi se swapem u virtuálu pracuje tak, že nejprve vytvoří soubor, otevře ho, smaže z filesystému, ale se souborem pracuje dál. Takže se pak stává to, že na NFS serveru vidím, že tam teče zápis 50MB/s, ale když chci přes inotify zjistit kam se to zapisuje, tak nic nezjistím.
tohle jsou ojedinělé případy rychlé práce v RAM
Vůbec ne. Ten smazaný soubor je pořád ve filesystému, má svůj inode, alokované bloky (které se podle potřeby ukládají na zařízení) a pracuje se s ním úplně stejně jako s kterýmkoli jiným souborem. Teprve když mu refcount klesne na nulu, fakticky se smaže (uvolní se bloky a inode), ale tak to opět funguje s jakýmkoli jiným souborem.
Proto se také syscall pro "smazání soubouru" jmenuje unlink()
. On totiž pouze odlinkuje adresářovou položku, ke skutečnému smazání dojde až ve chvíli, kdy na soubor neodkazuje žádná adresářová položka (mohlo jich být víc) a nepoužívá ho žádný proces. To je většinou hned, ale může to klidně trvat hodiny, dny nebo ještě déle.
Proč ale nemůžu sledovat třeba většinu r/w operací když otevřu třeba Firefox.Tady se lidi ptají na sledování zápisu/čtení souborů, ale neřeknou pořádně, co vlastně chtějí sledovat a proč (viz XY problem). "Sledováí r/w operací" je širokej pojem. Co přesně chceš udělat? Pokud chceš zjistit, co dělá konkrétní program - třeba Firefox - ve filesystému, tj. co kam zapisuje/čte, tak na to by ten
strace
měl posloužit celkom dobře.
Tady se lidi ptají na sledování zápisu/čtení souborů, ale neřeknou pořádně, co vlastně chtějí sledovat a proč (viz XY problem). "Sledováí r/w operací" je širokej pojem.Jelikož kolemjdoucí píše o tom, že to není součástí správců úloh v GUI, tak bych to viděl tak, že se potýká s tím samým co já. Vidím, že mi něco hrabe na disk, ale nevím co. Tak si chci spustit správce úloh a zjistit, že to dělá Chromium, protože se rozhodl pročistit cache s obrázky od hackerů z Alabamy. Pokud se nemýlím, tak s strace se musí proces už spouštět a tak nějak to vypisuje hrozně moc věcí a vytěžuje zbytečně procesor a určitě tu aplikaci zpomaluje... Což je v tom mnou uváděném případě naprosto nepoužitelné, protože jde o případ, kdy už mi nějaké aplikace běží a najednou se sami od sebe zblázní.
Vidím, že mi něco hrabe na disk, ale nevím co.Existuje
iotop
, případně htop
taky umí řadit podle I/O.
Pokud se nemýlím, tak s strace se musí proces už spouštět a tak nějak to vypisuje hrozně moc věcíNn, můžeš spustit strace připojením (attach) k existujícímu procesu. A můžeš mu říct, aby filtroval a vypisoval jen to, co chceš. Souhlasim, že to není takhle out of the box kdovíjak user-friendly a že by to šlo zabalit do přívětivějšího (G)UI.
Existuje iotop, případně htop taky umí řadit podle I/O.Umíš řadit nikoli podle MB/s, ale podle IOPS? (je mi jasné, že díky readahead tohle může klamat) Minimálně na rotačních discích je to také zajímavá metrika (e.g. zasekaný stroj kvůli tomu, že mailserver neustále přehazuje 4KiB soubory ve frontě, a v iotopu to není vidět, protože to je nepatrný datový tok (navíc pokud je to jenom přesun a fsync, tak se většina propálí na metadatech filesystému)).
a nedavno sem tu v diskuzi s nekym resil ze na GNU/Linux NEexistuje program co by monitoroval cteni/zapis konkretnich souboru
man strace
Případně dtrace
? Nevim teď, jak daleko jsou kluci s tím linuxovým portem, ale třeba by to šlo...
Programátoři tuší, jaké možnosti má C a že tohle je standardní způsob ošetření chybových stavů v C.Ta ošklivost toho kódu není daná (jen) limitacemi C. I v C by to šlo napsat pěkněji.
Ale zase je na tom hezky vidět, proč pozdější jazyky zavedly koncept výjimek.Výjimky některé problémy vyřešily, ale na to konto přinesly problémy jiné, neméně nepříjemné.
int function()
nebo sekvence if () else
atd. Protože to jsou prostě výrazové prostředky daného jazyka. Mezi výrazové prostředky nepatří jen klíčová slova, ale i konstrukce na vyšší úrovni. Je správně, nikoli špatně, pokud se tyhle konstrukce na vyšší úrovni opakují, tj. tu samou konstrukci všichni píšou stejně – každý pak na první pohled vidí třeba „aha, tohle je nekonečný cyklus“ a nemusí to detailně luštit z kódu.
No a to, co se v tom kódu opakuje, je pokud vím céčkový idiom pro ošetření chybového stavu. Takže na tom, že se opakuje, nevidím nic špatného, právě naopak – každému je to na první pohled jasné, nemusí každý ten if
podrobně číst ale může ho přečíst jako jeden blok „ošetření chyby“. Řešit to ošetření chyby nějakou funkcí, aby se ušetřil jeden řádek kódu, nebo dokonce nějakým makrem, by z mého pohledu bylo ke škodě věci, protože by se tím, zatemnilo, co ten kód vlastně dělá.
Jistě, že by se ten kód dal napsat úplně jinak. Třeba použít nějaký triviální parser, nebo dokonce plnohodnotný parser. Ale to, že by se to napsalo jinak, vůbec neznamená, že by to bylo hezčí nebo dokonce lepší. A bez toho, že někdo alespoň naznačí, jak jinak by to napsal, se to opravdu posoudit nedá.
Jinak já jsem na začátku reagoval hlavně na představu neprogramátorů, že jakmile se ve zdrojovém kódu nějaké části opakují, je to špatně.Aha, pardon, teď koukám, že jsem v tom původním komentáři přehlídl to "ne" v "neprogramátor"... Souhlasim, že ta metrika "pěknější kód" je do značný míry subjektivní...
Je to takovej levl junior:
const char *err[] = {"Can't parse num1", "Can't parse num2", ...} ret = sscanf(line,"%d %d ...", &num1, &num2, ...); if(ret < ITEMS) { if(!errno) { fprintf(stderr, "%s", err[ret]); else fprintf(stderr, "wtf?"); return FAIL; } return OK;
Tady se ale bavíme o tom, jak to hodnotí neprogramátoři
Opravdu? Já tady totiž o kus výš vidím komentář tohoto znění:
Řekl bych, že to bije do očí jenom neprogramátory. Programátoři tuší, jaké možnosti má C a že tohle je standardní způsob ošetření chybových stavů v C. Ale zase je na tom hezky vidět, proč pozdější jazyky zavedly koncept výjimek.
Podepsán je pod ním (technicky nad ním) jistý Filip Jirsák. A teď vidím, že Martina Mareše to do očí bije (mne mimochodem taky). Takže mi z toho logicky vychází, že pokud jste ten příspěvek nepsal v nějakém naprostém zatmění mysli a nehodláte to tvrzení odvolat, považujete Martina Mareše za "neprogramátora". A to mi připadá hodně odvážné - nebo spíš hodně hloupé.
sscanf
. Ale představte si, že by tam místo jednoduchých číselných údajů bylo něco jiného, třeba občas nějaký datum a čas v ISO formátu.
Pokud někdo do diskuse, kde už bylo jinými slovy řečeno „talk is cheap. Show me the code“ přispěje dalším komentářem bez kódu o tom, jak by se to dalo napsat lépe, sám se tím zařazuje mezi lidi, kteří jen povýšeně trousí moudra, že by to šlo napsat mnohem lépe, ale konkrétní kód neukáže.
Ne. Rozhodně ne. Pokud je kód očividně napsaný nešikovně a hloupě (a tohle je ten případ), nemá každý, kdo na to chce upozornit, povinnost trávit čas tím, že ho bude celý přepisovat, aby splnil vaše náročná kritéria.
Při vší úctě k Martinovi Marešovi, zařadit ho v tomto případě mezi „neprogramátory“ je myslím adekvátní reakce.
Po pravdě, nečekal jsem, že byste se omluvil, na to vás znám už příliš dlouho, ale musím přiznat, že touhle reakcí jste mne přesto dokázal překvapit.
Ta opakující se konstrukce, která připadá divná neprogramátorům, je standardní ošetření chyb v C – a nesetkáváme se s ní častěji v jiném kódu proto, že se na ošetření chyb často kašle.
Možnost, že by někomu nevadil způsob, jak se reaguje na chybu, ale prostě to, že je tam třicetkrát (možná víc, nemám chuť to počítat) za sebou prakticky totožný fragment kódu, vás opravdu nenapadla?
Ne. Rozhodně ne. Pokud je kód očividně napsaný nešikovně a hloupě (a tohle je ten případ), nemá každý, kdo na to chce upozornit, povinnost trávit čas tím, že ho bude celý přepisovat, aby splnil vaše náročná kritéria.Já jsem nepsal žádná náročná kritéria. Kritérium bylo jediné – aby ten kód byl lepší, než je ten současný. Což by nemělo být tak těžké, pokud ten kód je napsaný očividně nešikovně a hloupě. Zatím ale kromě silných řečí nemáme nic. Což mi připadá škoda, myslel jsem, že se my, kteří v C neprogramujeme, třeba dozvíme něco nového.
Možnost, že by někomu nevadil způsob, jak se reaguje na chybu, ale prostě to, že je tam třicetkrát (možná víc, nemám chuť to počítat) za sebou prakticky totožný fragment kódu, vás opravdu nenapadla?Myslím, že už jsem to vysvětloval v prvním komentáři. Ten fragment kódu je pokud vím idiom pro ošetření chybového návratového kódu. C na to nemá žádný syntaktický cukr, takže je ten idiom trochu ukecaný. Ale je to standardní konstrukce, a stěžovat si na opakování je přibližně stejné, jako kdyby si někdo stěžoval, že se při volání funkce vždycky opakují závorky.
Já jsem nepsal žádná náročná kritéria. Kritérium bylo jediné – aby ten kód byl lepší, než je ten současný.
Nemluvil jsem o kritériích pro kód, ale o kritériích pro diskusní příspěvky.
Ten fragment kódu je pokud vím idiom pro ošetření chybového návratového kódu. C na to nemá žádný syntaktický cukr, takže je ten idiom trochu ukecaný. Ale je to standardní konstrukce, a stěžovat si na opakování je přibližně stejné, jako kdyby si někdo stěžoval, že se při volání funkce vždycky opakují závorky.
A s takovým rozhledem máte tu drzost kádrovat lidi jako "neprogramátory"? V tom případě se přidávám k doporučení ohledně učebnice, zejména s důrazem na kapitoly o funkcích a cyklech (zbyde-li čas, možná i makra).
A s takovým rozhledem máte tu drzost kádrovat lidi jako "neprogramátory"?Já jsem nikoho nekádroval, v prvním příspěvku, kde jsem psal o neprogramátorech, jsem jenom vypíchl to, co o sobě dotyční napsali sami.
V tom případě se přidávám k doporučení ohledně učebnice, zejména s důrazem na kapitoly o funkcích a cyklech (zbyde-li čas, možná i makra).Víte, to je právě ta nevýhoda, že se nebavíme o konkrétním kódu. To se tady teď můžeme mlátit učebnicemi do nekonečna. Já se můžu jenom dohadovat, co přesně za kód vám připadá špatně, omlátit vám o hlavu, že to funkce ani cyklus nevyřeší, makra by pomohla, ale zase výrazně znepřehlední kód. Ten kód, který se na první pohled opakuje, je tohle:
if(token == NULL){ Trace($ERROR_MESSAGE); return false; }Někdo by možná k tomu problematickému kódu zařadil i předchozí výkonný řádek
token = strtok_r(NULL, " ", &savePtr);Tyhle bloky jsou ale roztroušené mezi jednotlivými řádky výkonného kódu, takže cyklus nijak nepomůže. Cyklus by se dal použít, pokud ten výkonný kód upravíte tak, aby si z nějaké deklarace načítal, jak má data parsovat, kam je uložit a co případně vypsat za chybu. Přidáte jednu úroveň nepřímého volání, pro parsování si vlastně vytvoříte takový jednoduchý DSL a můžete použít cyklus. Už jsem dříve psal, že je to jedno z možných řešení, a že v žádném případě takové řešení nebude automaticky přehlednější, než současný kód. Druhá možnost je nahrazení toho bloku funkcí. Ovšem ten blok se používá pro řízení toku programu, takže ten
if
a return
tam bude muset zůstat. Takže ten blok můžete zkrátit na tři řádky, místo současných čtyřech nebo pěti. Za cenu, že se dovnitř té funkce schová, že se tam vypisuje chybová zpráva, a za cenu, že se ta funkce bude volat přímo v podmínce if
u. Já to nevidím tak jednoznačně, že by ušetření jednoho nebo dvou řádků kódu bylo takovým kladem, aby to vyvážilo ty zápory.
if(attendError(token, $ERROR_MESSAGE)){ return false; }Možná jste myslel jinou úpravu, ale to se můžu jen dohadovat, když jste žádný kód nenapsal.
makra by pomohla, ale zase výrazně znepřehlední kód
Možná jsem divný, ale např.
if (PARSE_NUM(ppid, strtol, "Parent PID") || PARSE_NUM(pgrp, strtol, "Process group ID") || PARSE_NUM(session, strtol, "Session ID") || ...) return false;
mi přijde o hodně přehlednější než to, co tam vidím teď. Definice toho makra sice nebude zrovna umělecké dílo, ale zase o tolik hůře než jeden současný blok vypadat nebude. A hlavně tam bude jednou, takže zkontrolovat nebo někdy časem opravit ji také bude stačit jednou. Kdokoli bude dělat review, nebude muset pozorně pročítat 440 řádků nudného stále se opakujícího zdrojáku. Kdokoli bude potřebovat tu logiku trochu upravit, nebude muset provádět stejnou změnu na 49 místech, udělá to na jednom.
Cyklus by se dal použít, pokud ten výkonný kód upravíte tak, aby si z nějaké deklarace načítal, jak má data parsovat, kam je uložit a co případně vypsat za chybu. Přidáte jednu úroveň nepřímého volání, pro parsování si vlastně vytvoříte takový jednoduchý DSL a můžete použít cyklus.
No vidíte, že to jde…
Už jsem dříve psal, že je to jedno z možných řešení, a že v žádném případě takové řešení nebude automaticky přehlednější, než současný kód.
Asi by se to dalo napsat tak, aby to bylo nepřehlednější a hůře udržovatelné, ale to neznamená, že to tak být musí. Kdyby ty bloky byly tři (a měl jsem jistotu, že jiný podobný soubor parsovat nebudu), tak neřeknu, ale 49?
Pokud ten kód někdo bude číst, s největší pravděpodobností bude potřebovat vědět, co to makro kód dělá.
Základní informaci mu poskytne jméno, zbytek najde v komentáři nad jeho definicí, včetně popisu argumentů. Když se bude potřebovat podívat, co přesně dělá a/nebo jestli v něm není chyba, najde to na jednom místě, nebude jich muset procházet 49 a zkoumat, jestli se náhodou jedno záměrně trochu neliší nebo jestli v něm není překlep.
Váš kód … zase má tu nevýhodu, že případnou změnu parsování (bude tam nějaký nový údaj s jiným formátem) znamená změnit to makro, čímž se změní ten kód pro všechny ostatní případy, kde k žádné změně nedošlo.
Především bych to takhle pravděpodobně neudělal. To byl spíš takový nástřel, jak rychle a bezpracně dosáhnout podstatně lepšího výsledku. Hlavně se tu ale nebavíme o nějakém hypotetickém naprosto obecném problému, bavíme se o konkrétním kusu kódu, který parsuje /proc/${pid}/stat
, tj. soubor, jehož syntaxe se prakticky nemění - a když, tak leda tak, že přibudou další číselné sloupce.
Pokud by se přeci jen někde objevil sloupec s jiným formátem, nic mi nebrání si pro něj napsat jiné makro nebo funkci (s makrem jako wrapperem).
Jestli mi pořád nevěříte, schválně se zkuste podívat, jak vypadá kód na druhé straně, který ten soubor v procfs generuje. Konkrétně doporučuji podívat se, jestli je tam také padesát skoro stejných několikařádkových bloků nebo jestli je to řešené genericky. (A také doporučuji pozornosti komentáře týkající se zpětné kompatibility.)
Co kdyby těch bloků nebylo 49, ale 1500? Po celé aplikaci, protože by to byla konstrukce, která se v tom projektu tak používá.
Tím spíš bych to neřešil takhle stupidně, abych tam měl 1500 skoro stejných devítiřádkových kusů kódu. Podle okolností bych si buď napsal nějaký framework jako tady (spíš pro představu, je to pracovní verze a možná to nakonec bude celé vypadat úplně jinak) nebo použil něco hotového.
Samozřejmě se to dá napsat jinak a v mnoha případech ten jiný zápis bude lepší. Ale dovedu si představit situace, kdy je nejlepší právě ten současný zápis.
To já taky, třeba kdyby ty sloupce byly jen dva. Podstata problému je ale v tom, že tenhle konkrétní parser, tak jak je napsaný, je učebnicová ukázka, jak neprogramovat. A všechny ty vaše hypotetické úvahy, jak by se jiné řešení zkomplikovalo, kdyby cosi, na tom nemění zhola nic, protože tahle šílenost by v takových myšlenkových pokusech neobstála o nic lépe. Tohle je prostě prasárna, se kterou by vás kterýkoli příčetný a zodpovědný maintainer hnal svinským krokem.
A nebo je prostě jako obvykle problém jen v tom, že ostatní účastníci diskuse se zabývají praktickou stránkou věci a neberou ji jen jako argumentační cvičení.
Nějak nevidím rozdíl mezi vaší přípravou na hypotetickou situaci, že bude potřeba změnit způsob reakce na chyby, a mou přípravou na hypotetickou situaci, že stejným způsobem budu chtít parsovat jiný soubor.
On v tom vlastně až tak zásadní rozdíl není: v obou situacích na tom budete se stávajícím kódem o poznání hůř.
jeden vytržený soubor se zdrojovým kódem, bez znalosti jakéhokoli kontextu
Tady právě žádný kontext není potřeba, protože tak, jak je to napsané, mi to ve vedlejším souboru zcela určitě k ničemu nebude, ať už je v tom vedlejším souboru cokoli. Kontext začne být zajímavý až v okamžiku, kdy se začnu rozhodovat, jaké řešení zvolit, když to budu chtít napsat lépe.
zvlášť když tu všichni tvrdí, jak to snadno naprogramovat jinak, ale konkrétní ukázky tu máme jen dvě, a to ještě s komentářem „vlastně bych to takhle neudělal“
Začínám mít čím dál silnější pocit, že vy jste toho ve skutečnosti nikdy moc nenaprogramoval. Nebo jen předstíráte, že si neuvědomujete, jak velký rozdíl v časové náročnosti je mezi rámcovou představou, jak úlohu řešit, a prezentovatelným řešením odladěným aspoň natolik, abyste nemusel očekávat, že v něm během pěti minut někdo najde nějakou hloupou chybu? A že se kvůli vašim provokacím nikdo nebude psát se zcela konkrétním řešením, když jde o projekt, do kterého stejně nemá nejmenší chuť přispívat? (Ostatně, kdybych zrovna nedělal bisect, už bych se na tuhle diskusi dávno vykašlal i tak.)
Vhodný čas na vyčištění toho kódu totiž může být tehdy, až se ten kód bude příště upravovat – tehdy už totiž bude znám alespoň jeden případ, kdy ten kód bylo potřeba upravit, a bude možné kód zobecnit tak, aby usnadňoval právě ty úpravy, které se na něj doopravdy dělají.
A tímhle mne v tom pocitu jen utvrzujete. On jako do té doby nikdo nebude dělat review ani ten kód číst z jakéhokoli jiného důvodu? Lidem, kteří takovéhle věci píší, a stejně tak těm, kteří je obhajují, bych přál, aby aspoň tak rok jejich práce spočívala v nutnosti přečíst a pochopit cizí kód, který vidí poprvé v životě, rychle se v něm zorientovat a najít a opravit chybu. Možná by ani rok nebyl potřeba, aby se na to začali dívat trochu jinak.
On v tom vlastně až tak zásadní rozdíl není: v obou situacích na tom budete se stávajícím kódem o poznání hůř.Reagujete úplně na něco jiného, než je smysl sdělení.
Tady právě žádný kontext není potřebaSamozřejmě, že je kontext potřeba. Když nevíte, jaká jsou omezení, pravidla, zvyklosti nebo souvislosti, nemůžete vědět, zda to, co je podle vás očividně špatně, nemá nějaký smysl, který nechápete. Odsoudit cokoli na základě povrchních znalostí je strašně snadné.
Nebo jen předstíráte, že si neuvědomujete, jak velký rozdíl v časové náročnosti je mezi rámcovou představou, jak úlohu řešit, a prezentovatelným řešením odladěným aspoň natolik, abyste nemusel očekávat, že v něm během pěti minut někdo najde nějakou hloupou chybu?Ten rozdíl je tím větší, čím komplexnější a vrstevnatější to řešení je. Takže se také může stát, že dotyčný dospěje k názoru, že než to řešit hezky pomocí složitějších konstrukcí, řešení pak ladit a odchytávat hloupé chyby, vyplatí se to vyřešit přímočaře, prostě nakopírovat kód tak, jak se to má hodnotu po hodnotě parsovat, a nemuset už pak nic ladit a odchytávat hloupé chyby. Možná se to někomu líbit, pak se dotyční pohádají, zda se to má správně řešit pomocí
sscanf
, maker, funkcí nebo generátoru parserů, na ničem se nedohodnou a tak tam zůstane ten váš ošklivý kód až do doby, dokud to někdo nebude potřebovat opravdu upravit či zobecnit, a pak to přepíše.
On jako do té doby nikdo nebude dělat review ani ten kód číst z jakéhokoli jiného důvodu? Lidem, kteří takovéhle věci píší, a stejně tak těm, kteří je obhajují, bych přál, aby aspoň tak rok jejich práce spočívala v nutnosti přečíst a pochopit cizí kód, který vidí poprvé v životě, rychle se v něm zorientovat a najít a opravit chybu. Možná by ani rok nebyl potřeba, aby se na to začali dívat trochu jinak.Opravdu vám tenhle kód připadá na pochopení složitější, než kdybyste tam měl makro? Jako je pravděpodobné, že kdyby tam bylo použité řešení se
sscanf
nebo makro, nejspíš by nikdo nikdo z těch „sice nejsem programátor, ale tohle bije do očí“ svůj komentář nenapsal, ale obávám se, že důvodem by nebylo to, že by ten kód chápali a líbil se jim.
Samozřejmě, že je kontext potřeba. Když nevíte, jaká jsou omezení, pravidla, zvyklosti nebo souvislosti, nemůžete vědět, zda to, co je podle vás očividně špatně, nemá nějaký smysl, který nechápete. Odsoudit cokoli na základě povrchních znalostí je strašně snadné.
Snadné je spíš omíalt takovéhle obecné a bezobsažné fráze pořád dokola jen abyste nemusel připustit, že by to možná mohlo být i trochu jinak, než že vy jediný tomu rozumíte natolik, abyste nahlédl hloubku těch geniálních myšlenek a došlo vám, že ten kód není úplně hloupě napsaný, ale že je vlastně mnohem chytřejší, než kdybychom ho psali my ostatní.
Ten rozdíl je tím větší, čím komplexnější a vrstevnatější to řešení je. Takže se také může stát, že dotyčný dospěje k názoru, že než to řešit hezky pomocí složitějších konstrukcí, řešení pak ladit a odchytávat hloupé chyby, vyplatí se to vyřešit přímočaře, prostě nakopírovat kód tak, jak se to má hodnotu po hodnotě parsovat, a nemuset už pak nic ladit a odchytávat hloupé chyby.
Jasně, "a nemuset už pak nic ladit a odchytávat hloupé chyby". Bylo by to zábavné, kdybych neměl podezření, že tomu snad opravdu věříte.
Možná se to někomu líbit, pak se dotyční pohádají, zda se to má správně řešit pomocí sscanf, maker, funkcí nebo generátoru parserů, na ničem se nedohodnou a tak tam zůstane ten váš ošklivý kód až do doby, dokud to někdo nebude potřebovat opravdu upravit či zobecnit, a pak to přepíše.
Především by v příčetně a zodpovědně maintainovaném projektu takováhle hrůza zůstat neměla z toho prostého důvodu, že by se tam nikdy neměla vůbec dostat. "Uděláme to pořádně teprve až to bude potřeba upravit" je naprostý nesmysl a cesta do pekel. A vůbec celý ten argument ignoruje, že se sice mohou rozcházet názory na to, jestli je elegantnější to či ono řešení, ale že to, o kterém se celou dobu bavíme, je úplně jiná liga. Prostě jako kdyby se fandové fotbalu bavili, jestli se jim víc líbí hra Realu, Bayernu nebo Juventusu, a vy se vytasil s tím, že podle vás nejhezčí fotbal hraje FC Amfora. A pak do krve obhajoval, že váš názor je stejně hodnotný jako ten jejich.
Opravdu vám tenhle kód připadá na pochopení složitější, než kdybyste tam měl makro?
Na pochopení čeho přesně? Na pochopení toho, co by asi tak měl dělat, to vyjde asi tak nastejno. Ale na to, abych mohl říci, co opravdu dělá… na to je ten stávající kód řádově složitější. A problém (jeden z mnoha) je v tom, že to druhé je po čertech důležitější než to první.
Nemám nejmenší tušení, na kterou část mého komentáře tím prefabrikátem reagujete - a vlastně už mne to ani nezajímá. Až (jestli) se někdy budete chtít bavit o programování, můžeme se k tomuto tématu vrátit. Abych vám dál dělal sparingpartnera pro vaše cvičení v abstraktní rétorice, na to nemám čas ani náladu.
Několik lidí, kteří se programováním v céčku opravdu zabývají a mají i nějaké ty zkušenosti z praxe a skutečných softwarových projektů, se vám tu pokoušelo vysvětlit, že je ten kód zásadně špatně napsaný, přistoupili i na vaši hru na nechápavé dítě a trpělivě vysvětlovali proč a pak dokonce i to, jak by se to dalo udělat lépe. Vše marno, vy si dál vesele dokola opakujete své bezobsažné fráze a trváte na tom, že ten kód je vlastně úplně v pořádku.
Ten fragment kódu je pokud vím idiom pro ošetření chybového návratového kódu.Ano a jako takový je ten idiom v pořádku. Nicméně pokud jsi nucen vložit tento idiom za téměř každou řádku užitečného kódu v té funkci, je to celkem slušná indikace, že je něco špatně. Pokud tohle nevidíš, myslim si, že nemá smysl řešit konkrétní alternativní kód. Navíc tak, jak jsi to položil, můžeš vždycky na jakýkoli konkrétní kód s kterým kdokoli přijde namítnout, že elegance kódu je subjektivní, tudíž to nic nedokazuje. Z tohohle důvodu neočekávám, že by se kdokoli z diskutujících babral z psaním kódu, vzhledem k tomu, že z toho nekouká žádný užitek.
Mimochodem, je tu několik komentářů, jak je něco evidentně a jednoznačně špatně, ale v žádném z těch komentářů není napsáno, co přesně je špatně – a ty různé náznaky směřují každý jiným směrem.Protože je toho špatně vícero a každému vadí něco trochu jiného? A taky protože je možné se o tom bavit na různých úrovních, tj. parsování
/proc/pid/stat
konkrétně nebo nějakého podobného textu obecně nebo obecně error handling, atd., je to potenciálně velmi široké téma.
Začal bych dokumentací, která specifikuje scanf flagy pro parsování jednotlivých sloupců a dokonce už tady i někdo poslal celkem rozumně vypadající nástin kódu, což jsi nezaznamenal nebo vyignoroval, nevim.
Jinak to, že spousta lidí má čas napsat "to je ale ošklivý kód", ale už nemá čas/chuť vymýšlet řešení problému, který 1. se jich netýká, 2. je už dávno vyřešen někde jinde a 3. chce ho po nich Filip Jirsák se svým přístupem k diskutujícím, mi nepřijde naprosto nijak divné a nijak to neimplikuje, že to řešení neexistuje nebo že tady je nějaká záhada/detektivka, jakou z toho děláš.
Jestli tě to fakt tak zajímá, tak si projdi tu dokumentaci a třeba zdroják jiných utilit, které tohle řeší, třeba najdeš něco zajímavého. Mně se během psaní komentáře dokompiluje projekt, což je jediný důvod, proč tady teď komentuju a víc tomu nedám ani sekundu a ostatním doporučuju to samé.
Protože je toho špatně vícero a každému vadí něco trochu jiného?Pokud každému vadí něco jiného, není náhodou možné, že jiné věci zase považuje za správné – a kdyby je někdo jiný opravil, považoval by to za zhoršení? Neměl by si toho náhodou být programátor vědom, že často je to jen otázka vkusu – a že tedy psát obecné komentáře „to musí každý vidět, jak je to špatně“, je poněkud hloupé?
je to potenciálně velmi široké témaSouhlasím. Je to široké téma, každý může vidět problémy někde jinde, tudíž obecně ten kód odsoudit, jak je to špatně napsané, je póza ale ne konstruktivní příspěvek do debaty.
Začal bych dokumentací, která specifikuje scanf flagy pro parsování jednotlivých sloupcůPokud vám
scanf
vyhovuje pro parsování těch dat. Co když je ve vedlejším souboru parser jiného formátu, na který už scanf
nestačí? Je pak lepší jednou použít scanf
a podruhé strto*
funkce, nebo je lepší to sjednotit a všude použít stejný princip?
dokonce už tady i někdo poslal celkem rozumně vypadající nástin kódu, což jsi nezaznamenal nebo vyignoroval, nevimAno jedno, ani druhé, ale tohle:
Já tady vidím jediný příspěvek s kódem, a autora toho kódu oceňuji, že jako jediný našel odvahu jít s kůží na trh. Přestože si nemyslím, že by jeho kód byl lepší nebo horší – je prostě jen jiný, má jiné nedostatky a jiné přednosti.
že tady je nějaká záhada/detektivka, jakou z toho dělášJá tu z toho žádnou záhadu nebo detektivku nedělám. Pouze mi připadalo zajímavé, kolik lidí si musí kopnout do autora kódu, kterému vůbec nerozumí, vůbec netuší, jak by měl vypadat, jenom někde zaslechli, že je prý chyba, když se ve zdrojovém kódu něco opakuje.
Pokud každému vadí něco jiného, není náhodou možné, že jiné věci zase považuje za správné – a kdyby je někdo jiný opravil, považoval by to za zhoršení?
Tak se schválně zeptám: kdo další si ještě myslí, že parsovat řádek s 49 čísly oddělenými mezerami tímto rukodělným způsobem je v pořádku?
Přestože si nemyslím, že by jeho kód byl lepší nebo horší – je prostě jen jiný, má jiné nedostatky a jiné přednosti.
Jestli to opravdu vidíte takhle, tak se asi opravdu nemáme o čem bavit, protože každý žijeme v jiné realitě.
Pouze mi připadalo zajímavé, kolik lidí si musí kopnout do autora kódu, kterému vůbec nerozumí
1. Kromě asi dvou přitroublých výkřiků, které nikdo nebral vážně, nikdo nekopal do autora, ale to toho, jak je ta funkce napsaná. To je dost zásadní rozdíl. 2. Jak jste přišel na to, že tomu kódu "vůbec nerozumíme"?
Tak se schválně zeptám: kdo další si ještě myslí, že parsovat řádek s 49 čísly oddělenými mezerami tímto rukodělným způsobem je v pořádku?Neřekl bych, že jediný účel té aplikace je parsovat řádek se 49 čísly. Díval se někdo na další zdrojáky? Jestli se v nich třeba nevyskytují parsery napsané stejným způsobem?
Jak jste přišel na to, že tomu kódu "vůbec nerozumíme"?Nějak vás nevidím mezi autory komentářů, které zde byly před tím, než jsem napsal svůj první komentář v této diskusi. Komentáře, na které jsem reagoval, převážně opakovaly „nevím, co co tam jde, ale vidím tam opakující se podobné bloky kódu, a někde jsem zaslechl, že je to prý prasárna“.
Díval se někdo na další zdrojáky? Jestli se v nich třeba nevyskytují parsery napsané stejným způsobem?
V čem by to pomohlo? Vždyť to by bylo ještě horší, než kdyby tohle byl jediný náhodný úlet.
Podívat se vedle by dávalo smysl, kdyby se tu implementovala zdánlivě zbytečně obecná parsovací funkce, když zrovna tady by stačila jednodušší. Pak by mělo smysl zkontrolovat, jestli se někde jinde využívají i ty další možnosti. Ale tohle není ten případ. Tady je neprakticky, nepřehledně a neudržovatelně napsaný kus kódu, který je izolovaný a na nic jiného nenavazuje a ani navazovat nemůže.
strto*
funkcí, protože by ty formáty byly sice jednoduché, ale už dost složité na to, aby se daly rozparsovat jedním voláním sscanf
. A teď vám k tomu přibyde devátý formát, který se shodou náhod zrovna dá rozparsovat jením voláním sscanf
. Čemu dáte přednost – tomu, aby ten jeden parser vypadal úplně jinak než ty ostatní, ale byl hezčí, a nebo tomu, aby všechny ty parsery používaly stejné konstrukce?
Pokud vám scanf vyhovuje pro parsování těch dat. Co když je ve vedlejším souboru parser jiného formátu, na který už scanf nestačí? Je pak lepší jednou použít scanf a podruhé strto* funkce, nebo je lepší to sjednotit a všude použít stejný princip? (...) Přestože si nemyslím, že by jeho kód byl lepší nebo horší – je prostě jen jiný, má jiné nedostatky a jiné přednosti.Ano, tohle je přesně důvod, proč nemělo/nemá smysl psát ti tady jakékoli příklady alternativní verze... A pak kdo tady pózuje...
Pouze mi připadalo zajímavé, kolik lidí si musí kopnout do autora kódu, kterému vůbec nerozumí, vůbec netuší, jak by měl vypadat, jenom někde zaslechli, že je prý chyba, když se ve zdrojovém kódu něco opakuje.Smysl toho kódu je zjevný a ano obecně kód se zbytečně nízkým SNR je chyba, na tom nění co řešit, není to detektivka.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.