Tohle jsem zazil nekolikrat. Prevzal jsem sw ktery byl na stare technologii a mel jsem na vyber. Bud to zuby, nechty udrzovat nebo prepsat do noveho.
Prepsani bolero. Objevovali se tam takove detske chyby. Nakonec si to sedlo a ja jsem rad ze jsem do toho sel.
Tak proto gentoo dodava binarky rustu, protoze to ani samo sebe zkompilovat nezvladne ... a i kdyz se o to nekdo pokusi, tak to bleje warning na kazdym radku kodu. Legracni je na tom predevsim to, ze 99% tech warnigu je prave na tema memory unsafe.
Jestli vůbec.
1) Ani safe Rust tohle nezaručuje, protože v kompilátoru jsou bugy (staré i několik let, kdy v safe kódu můžete přistupovat třeba k již uvolněné paměti).
2) Každá pátá knihovna na crates.io obsahuje unsafe kód, který může být špatně. V některých případech ani nejde říct, zda je dobře či špatně, protože Rust zatím nemá žádnou specifikaci pro aliasing ukazatelů, takže se vlastně nedá říct, zda třeba tokio je v pořádku nebo ne.
3) Psaní unsafe kódu v Rustu je těžší než psaní C kódu (nebo Odin, Zig, C3),
protože po programátorovi se očekává mnohem víc - ty invarianty co musíte dodržet jsou mnohem složitější a je mnohem snazší je porušit. Navíc ten program v Rustu často může zatím fungovat, i když ve skutečnosti obsahuje nedefinované chování.
Jo, jenže v Rustu se ty problémy (všeho typu) postupně řeší. Problémy dané použitím C se principiálně nevyřeší nikdy.
Bugy v kompilátoru věřím, že vyřeší.
Ale množství unsafe kódu v různých knihovanách asi ne - to by se musel Rust změnit, aby to co se dnes píše v unsafe kódu, šlo napsat v safe kódu a běželo to stejně rychle (nebo rychleji).
Ideální by bylo, kdyby Rust přišel s nějakým jednoduchým modelem pro aliasing, který zároveň umožňuje optimalizace. Jediný kandidát je zatím Tree Borrows, ale úplně jednoduchý není (možná totiž žádný jednoduchý model pro aliasing ani neexistuje).
A proč je unsafe kód v rustu takový problém?
Ten unsafe kód je krásně izolovaný a obecně ho není moc. Třeba v C++ je unsafe všechno by design, v rustu se dá všechno dohledat a třeba auditovat.
Unsafe je pro systémový jazyk prostě potřeba.
> A proč je unsafe kód v rustu takový problém?
Protože ty chyby v něm jsou vidět hůř než v C. Viz třeba problémy, co našel nástroj Miri.
> Ten unsafe kód je krásně izolovaný a obecně ho není moc.
Bohužel ten problém s unsafe kódem se může projevit i mimo unsafe blok. Takže verifikaci musíte provádět většinou na celém modulu včetně safe částí. A ověřujete, že jakékoliv volání safe funkce nezpůsobí nedefinované chování. A pak, že jakékoliv volání unsafe funkce, které splňuje invarianty (z dokumentace), nezpůsobí nedefinované chování.
A ten hlavní problém jsou IMO právě aliasing pravidla, která jsou přísnější než v C.
Například jsem přepisoval kód ze standardní knihovny Rustu do C3 a výsledek byl zhruba 3x kratší - protože v Cčkovém jazyce jsem nemusel řešit problémy s aliasingem (konkrétně se jednalo o B-strom a soubor node.rs, který měl v Rustu 1800 řádků kódu a v C3 600 řádků - algoritmus zůstal stejný).
K diskuzi doplním, že ačkoli C/C++ jsou "unsafe", je k nim spousta externích nástrojů, které typické chyby, které Rust odhaduje již v době kompilace, také najdou. Takže jazyk C/C++ jako takový "bezpečný" není, ale ekosystém jako celek ano. Jen to není by default a součástí jazyka jako takového.
12. 11. 2025, 15:26 editováno autorem komentáře
Vývojáři kernelu si to nemyslí. A Rust taky nepodchytí všechno, takže stejně nakonec bude koexistovat s externími tooly jako ten Miri.
Takto jsem to nemyslel.
Ono teď tu máme nový memory safe jazyk, a hle... Další a další CVE, dokonce v tak důležité aplikaci jako je sudo. Nakonec zjistíme, že šance na logickou chybu je mnohem větší než šance na nějaký buffer overflow.
Co jsem si všiml, tak hlavně v rustu si hodně lidí myslí, že když se to zkompiluje, tak to je bezchybné. Já se osobně ale přikláním k tomu, že jsou potřeba i testy, a hodně.
S tím nesouhlasím.
Já píšu i asm, tam kde to má benefit, a abych byl upřímný, tak udělat chybu v asm, díky které projdou testy a program nespadne je mnohem mnohem těžší, než udělat chybu třeba v C++.
V asm se nepíšou aplikace, jen kritické funkce, které není problém kompletně otestovat.
Třeba v golangu se asm píše běžně (je to jediná možnost jak něco optimalizovat v go) a není to v podstatě žádný problém pro celý ekosystém - neslyšel jsem o chybě v asm, spíš zase ty logické chyby v go, popř. data race.
12. 11. 2025, 11:30 editováno autorem komentáře
Dobře, ale jak to rozporuje můj příspěvek? "Masově" znamená mj. "kdekdo", "velký projekt" a "často".
Psaní unsafe kódu v Rustu je těžší než psaní C kódu
Jen taková OT myšlenka, který mě napadla už když jsem poprvé viděl syntax Rustu a nutnosti u každé proměnné označovat, jestli je to move, borrow apod, tak jsem se zamyslel, proč to tam vůbec je a jestli vůbec existuje jazyk, který by všechny tyhle problémy převedl na formální správnost, tedy zkompiluju pouze formálně správný kód, u kterého lze dokázat nějakou kvalitu. Potom by bylo jednak naprosto jasné, co se musí a nemusí kopírovat a hlavně by se snadno dělalo něco (můj sen), jako automatická paralelizace do mnoha threadů (což je třeba u share nothing modelu trivka).
Ono těch chyb v GNU Coreutils je ovšem taky hodně, jen se o každé nepíšou zprávičky. Řada z nich se týká právě paměťové bezpečnosti, takže má smysl se tím zabývat. Přechod na úplně novou implementaci ovšem bolí.
> Řada z nich se týká právě paměťové bezpečnosti, takže má smysl se tím zabývat.
Je otázka, jestli Rust je to správné řešení.
Kdyby tohle chtěl Rust vyřešit, tak by IMO neřekl, že aliasing pointerů nebo referencí je nedefinované chování. Jenže oni to řekli, protože chtějí optimalizace. Takže na chyby náchylnou práci nechali tvůrci Rustu na programátorech.
Jenže konkrétně aliasing je hodně velký průser. V C++ je aliasing dokonce by-design v celé standardní knihovně (např. iterátory, že jo...). Takže compiler vždycky musí předpokládat aliasing, což omezuje optimalizace, které může udělat.
Za mě omezit nebo úplně odstranit aliasing je mnohem lepší než cesta C/C++, kde je restrict, který ale skoro nikdo nepoužívá.
> Takže compiler vždycky musí předpokládat aliasing, což omezuje optimalizace, které může udělat.
Přesně tak, přicházíte o optimalizace, ale je to jednodušší na psaní pro programátora.
No hlavně by programátor C++ měl dodržovat strict aliasing rules. Pak mají překladače volnější ruce.
Přistupovat do jedné proměnné přes dva ukazatele (různého typu) je UB.
Používání dvou iterátorů na dvěma různými ranges se předpokládá, že se nepřekrývají, jinak UB
Přístup iterátorem mimo range, ve kterém je platný je UB.
Jinak jsou překladače v optimalizacích velice dobré, umí detekovat, kdy hrozí nebezpečí aliasingu a kdy ne (a v jaký okamžik je třeba zneplatnit cachovaný obsah všech ukazatelů, kvůli nebezpečí aliasingu)
Spíš mi vadí, že pokud překladač něco takového vidí, že nevydá žádné warningy, nebo že jsou ty warningy na nějakém hluboko-obskurdním levelu defaultně vypnuté.
Ono je rozdíl mezi "dodržovat něco" a když je něco "vyžadované".
Já sice hodně dělám C++, ale vidím hodně výhod právě v rustu - ty omezení mají smysl a třeba iterátory v rustu jsou mnohem líp vymyšlené než ty v C++. Ale nechci se tady pouštět do nějaké hlubší diskuze. Dlouhodobě se asi přikláním spíš k rustu než C++, ale C++ a golang mě teď živí.
Ano výhodou Rustu je, že to kontroluje a když není něco splněno, tak se to nepřeloží
- nevýhodou je pak boj s překladačem
Oproti tomu v C/C++ je spoustu věcí jednoduše označeno UB, a pokud to člověk použije, je to jeho chyba.
A ano, programátoři mají často problém se skillem, proto je Rust oblíbený, který jim spoustu věcí nedovolí a vodí je za ručičku.
Nedávno jsem řešil jak v rustu udělat permutaci prvků v poli safe. Visí to na swapování, které samo osobě není safe code. Pokud chci permutovat do jiného kontejneru, tak je to unsafe taky (nebo vyžadovat použití Option). Prostě boj s překladačem (bylo to cvičení na prozkoumání výhod a nevýhod destruktivního move).
Dělala bych to stejně. Ano, interní implementace využívá unsafe, ale prokazatelně sound.
12. 11. 2025, 13:54 editováno autorem komentáře
Jenže to je právě ten problém.
Já dělal na projektech v C++ co měly miliony řádků kódu a to nejde uhlídat v teamu 10-20 lidí s různou senioritou. UB je věčný boj - znamená to nasadit UBSAN, ASAN, MSAN a TSAN (který má nějaké celkem vážné omezení) a ani sanitizéry nenajdou všechno a nejdou použít na některé testy, které třeba vyžadujou hodně paměti (ASAN) nebo výkonu (UBSAN).
Takže já bych řekl, že právě ty omezení v rustu co přináší memory safety začínají být účinné až se ten projekt rozroste. Třeba refactoring většího množství kódu v C++ je noční můra a pokaždné, když se udělá, tak se něco rozbije.
No já taky. Ale většinou je to skill issue.
- drtivá většina dneska neprogramuje v C++ ale v C with classes
- dodneska se masivně zneužívá preprocesor, někdy i blbě (například #define SUM(a,b) a+b )
- a nebo se programuje ve stylu Javy kdy mám rozvinutou hierarchii tříd, které nedávají smysl.
- minimum lidí zná chytré ukazatele
- velké množství lidí používá "raw" pole.
Je to problém. Rust těží z toho, že nic takového tam nejde dělat. V C++ to taky lze psát bezpečně. Chce to nasadit nástroje, které odmítnou jakýkoliv kód, který nese známky C stylu programování. Takové existují.
Odmítnout kód, který nese známky C, nestačí, pořád nelze psát v C++ bezpečně. Problémem C++ jsou lifetimes, protože C++ překladač nemá dostatek informací k tomu, aby dokázal inferovat lifetime objektu a tím pádem ani nemůže vědět, jestli je ukazatel na objekt stále platný, nebo ne.
Triviální přiklad:
auto a = std::make_unique<int>(0); auto b = std::move(a); std::cout << *a; // UNDEFINED BEHAVIOR
Všechno je to moderní C++ se smart pointery, žádné C a stejně je tam UB. Takové věci bohužel nejde na větším projektu ve více lidech uhlídat a C++ tooly to z principu taky nemůžou umět.
No to bylo jako "na začátek"
Zrovna tenhle příklad je snadno detekovatelný.
Bohužel je, všechny tři překladače to nedokáží detekovat, což považuju za chybu překladačů. Je to dokonce tak legrační že
gcc kód přeloží jako
mov eax, DWORD PTR ds:0
Což mě hlava tedy nebere, že to někomu nepříjde divný. To je snad na bug report na gnu!
clang pro jistotu celý příkaz vynechá (nezavolá cout)
Microsoft to přeloží tupě bez dalších optimalizací (takže udělá dereferencu null)
Hodně jsem zklamán zejména ze schopností překladačů. Ty překladače to UB vidí, ale nevypíšou žádnou hlášku.
Ano, všechno se dá svést na skill issue. Takže teoretický dokonale kulatý programátor ve vakuu dovede napsat a dlouhodobě udržet memory safe C++ kód. Teď ještě prokázat možnost existence takového člověka.
Teď vám píše :-D
Zcela vážně, netuším co je to memory unsafe. V C++ programuju denně a sigsegv, ani memory leak jsem pořádně neviděl pořádně roky. Pokud se budu hodně snažit, třeba psát nějakou super optimalizaci v c-like kódu, tak samozřejmě takovou chybu udělám. Pokud ale budu správně používat všechny hlavní vlastnosti C++, tak to fakt je skill issue tam udělat chybu. Lidi jsou často děsný prasata a dokážou vymýšlet strašný elektrárny.
Vážně je skill issue nevšimnout si, že se provedl move na smart pointeru a pak se později dělá jeho dereference? V kódu to nemusí být hned za sebou, move se udělá v jedné funkci a dereference v jiné a je z toho UB. Projekty se v čase vyvíjí a lidé do nich přicházejí a zase odcházejí a není v možnostech člověka udržet větší projekt celý v hlavě, zvláště když na něm pracuje více lidí současně.
Není to skill issue - skill issue je jen takový argument od lidí, co už dělají 2 dekády C++ a myslí si, že chyby nedělají. Jenže oni o nich jen neví a pak budou nějaký problém hledat 2 týdny, až se to projeví...
Já chyby dělám taky, a proto píšu hodně testů - protože pak můžu spát a dělat i refactoring, kterému pak víc věřím.
Jediná možnost, jak psát relativně safe C++ kód je rozdělit věci na malé otestovatelné celky a ty pak propojovat - jenže to někdy vyžaduje víc času, než který člověk v realitě má.
Protože všichni máme rádi svět, kde se lidé bojí jakékoli změny, protože na každou chybičku se vyrojí 111 Tomů, kteří ji zlomyslně odvážným omlátí o hlavu.
Chápu, že pokud se to málo používá, tak se to moc neotestuje, takže zařadit to distribuce je potřeba. Akorát si nejsem jistý, jestli bylo rozumné takhle klíčovou komponentu vyměnit půl roku před vydáním LTS verze.
Lenže ono to vôbec nebolo potrebné. Celé toto nahrádzanie funkčného kódu nedokončenými "pet projektami" slúži len na uspokojenie potrieb pár aktivistov.
Co budeš dělat, až ty "geniální" C utility vymřou a nikdo po nich nevzdechne? Tvářit se, že jsi tohle nepsal?
Že jsou to nedokončené pet projekty máte něčím podložené? Ony totiž jsou chyby i v těch starých projektech – také je proto budete nazývat nedokončenými pet projekty?
Kdyby se všichni řídili vaší představou, že všechno nové musí být dokonalé, jinak se to nemá používat, neměli bychom žádný internet a používali bychom ještě děrné štítky. Resp. ani ty ne, protože i ty byly svého času novinkou.
No, děrné štítky jsou starší než počítač, těm toho ve výpočetní technice moc nepředcházelo. Ale magnetické pásky jsou nesmysl. Dají se poškodit magnetem, a to že díky nim nejde udělat chybu chybným pořadím vložených štítků? Skill issue.
13. 11. 2025, 08:20 editováno autorem komentáře
Děrným štítkům předcházelo psaní na papír, před tím se třeba tesalo do kamene. Že text psaný na papíře nejde automatizovaně zpracovat? No, dnes OCR funguje celkem obstojně.
Každopádně pokaždé, když si někdo myslí, že celý historický vývoj až do jeho mládí byl v pořádku, ale všechno, co se změnilo v jeho dospělosti, je špatně, měl by se vážně zamyslet nad tím, zda opravdu žije v tak zlomové době, která za celou existenci lidstva před tím nenastala. A nebo zda náhodou nepřestal být otevřený novým věcem.
Rád bych připomenul, že hustota záznamu tesáním do kamene je sice velmi nízká, ale mimořádná trvanlivost byla dlouhodobě prokázána. S trvanlivostí papíru to je o něco horší, ale stále je dostatečná (týká se i děrných pásek a štítků) a text na papíru je stále technologicky dostatečně nezávislý (čtenář potřebuje nanejvýš brýle). O trvanlivosti a nezávislosti pozdějších médií, bychom my, co se zabýváme retro počítači mohli dlouze vyprávět. Obvykle čím modernější a čím hustší záznam, tím hůř. Musí se to opečovávat, ověřovat, řešit kompatibilita, zálohovat na nová média...
Po generacích před námi zbyly např. fotky a filmy. Po lidech co mají fotky a videa v (jen) cloudu nezbude nic.
Zdaleka nezbyly všechny fotky a filmy. Ostatně stejně jako zápisy vytesané do kamene i papíry. Digitálních fotek a videí pro nás zůstává spousta na sociálních sítích, na Youtube… Na absolutní množství toho po nás zůstává daleko víc. A vůbec by mne nepřekvapilo, kdyby toho zůstalo víc i relativně, v poměru k záměrně uloženým fotografiím a videím (nepočítám to, co bylo promazáno hned v nějakém úvodním vytřídění). Z toho, co chceme dlouhodobě zachovat, toho s největší pravděpodobností zůstává daleko víc, než dříve. Ony se totiž ty nůžky rozevřely – to, co nepotřebujeme uchovávat dlouhodobě, ukládáme na média, která jsou daleko levnější, ale dlouhodobě nevydrží. Ale to, co chceme uložit opravdu dlouhodobě, umíme uložit daleko spolehlivěji, než dříve.