Co je to ten koncept s názvem barrels? Nic mi to neříká...
ale jak píše Filip Jirsák, výměna C za jiný jazyk problém kritických chyb nevyřeší. Ani rust na to nemá lék, ale dá se v něm hromady chyb přirozeně vyhnout. Pořád tady máme velkou část chyb typu, že zapomeneš validovat vstupu nebo sezení, před těmi tě jazyk nezachrání.
Mysli na to, že když někdo mluví o nějakém jazyku, musíš vzít v potaz kontext, ve kterém to řekl. Tady dostal dotaz z publika...
Nevíš o tom, že jsi udělal chybu, to je rozdíl.
Asi nejvic zatizenej SW, co jsem vyvinul, je system, ktery poskytuje jednotne BSD socket API pro prenost cplane v mobilnich sitich. Bezi to na 3 milionech CPU 24/7, 32bit/64bit i big/little endian. Jaka asi muze byt pravdepodobnost, ze tam je chyba, ktera by se neprojevila?
Do kernel poslu tak 3 opravy rocne a nepamatuju si, kdy naposledy bych opravoval chybu, ktera by v Rustu nemohla nastat. KASAN, lockdep atd uz jsou na takove urovni, ze se rozdil z hlediska bezpecnosti mezi C a Rustem minimalizuje. Osobne vidim vyhodu Rustu v tom, ze veci, ktery si v C clovek delal sam, a kazdej projekt je pak mel jinak, se v Rustu delaji vsude stejne, protoze jsou uz v samotnem jazyce, takze je snazsi na projekt pribrat noveho cloveka. Zejmena pokud se bude jednat o high-level aplikaci, kde nejsou tak prisne naroky na vykon, aby se treba synchronizace musela optimalizovat rucne.
V soucasnosti Rust sleduju spis pasivne, protoze porad pisu kod pro platformy, kde neni podporovanej (treba be mips64), ale ocekavam, ze v pristi dekade ho budu vic pouzivat, protoze exoticke platformy postupne zastaraji a vse bude bud x86 a nebo arm64. Nepovazuju ho ale za nejakou spasu a neco, co by melo vyraznejsi vliv na mnozstvi chyb v jadre.
Tomu se říká testování "happy path". Aneb, za běžného provozu se chyba neprojevuje.
Bezpečnostní chyba se třeba během provozu neprojeví. Ale pořád tam je (třeba použité strcpy bez kontroly délky).
Stejně tak může být problém v souběhu s nějakou fakt divnou podmínkou (pokles napětí v síti a rozhození časování paketů..). Nebo se po letech objeví chyba v CPU, kernel zavede "mitigation" a jiné časování cache udělá něco zajímavého (viděl jsem).
Statistiky objevených chyb ukazují, že C je velice náchylné na paměťové chyby. A už na univerzitě nás učili, že "každý program obsahuje alespoň jednu chybu". Po cca 25 letech praxe jim musím dát za pravdu.
V dokonalé programy tudíž nevěřím.
Jenze chyba soubehu muze byt stejne tak v Rustu jako v C. Za prve ta chyba muze byt v samotnem runtime Rustu a za druhe je naivni si myslet, ze veskera synchronizace se bude delat prostredky, ktere Rust poskytuje, at uz z duvodu vykonu a nebo z duvodu synchronizace s necim externim (treba HW). Kdyz proste HW bude cist addresu z RAM a program ji zapise jen do cache, tak to nebude fungovat a je uplne jedno, jakej jazyk se pouzil.
Chybu souběhu ve smyslu data race nejde v Rust safe kódu udělat, Rust odchytí data race při překladu. Jiné chyby souběhu (např. deadlock na mutexu) v Rustu možné jsou. Nicméně i tohle je velká pomoc, data race je častá chyba a hodně nepříjemná, protože se nemusí dlouho projevit a špatně se hledá. Address sanitizery v C chytí data race jen v runtime a jen v případě, kdy se problematická část kódu skutečně vykoná. Rust překladač chytí data race při překladu kdekoliv v kódu.
Ano, bohužel ale nejde v Rustu mít užitečný program bez unsafe kódu, protože potřebujete volat věci z vnějšku nebo nechat svůj kód volat něčím z vnějšku.
Unsafe kód je ve standardní knihovně a i v různých dalších balících. Pokud je v něm chyba, tak garance, co typový systém Rustu dává, nemusí vůbec platit.
Ale unsafe třeba nevypíná borrow checker. Jen explicitně žádá programátora, aby potvrdil (a doložil komentářem), proč je to v pořádku.
Rozdíl oproti C je v tom, že v C unsafe je celý program. V Rustu se to unsafe zdokumentuje, zapouzdří a obslužný kód už ho nemusí řešit.
Mohou se objevit logické chyby? No, ano, mohou. Je to stejně pravděpodobné jako v C? Ze zkušenosti je jich výrazně méně.
A i v Rustu platí, že nevěřím na dokonalé programy. Jen se méně bojím k tomu pustit i ostatní.
Z mé zkušenosti je výrazně těžší psát unsafe kód v Rustu, než psát kód s ukazateli v C. Pravidla v Rustu pro aliasing referencí jsou přísnější než v C a unsafe kód je dovoluje porušovat.
> Ale unsafe třeba nevypíná borrow checker. Jen explicitně žádá programátora, aby potvrdil (a doložil komentářem), proč je to v pořádku.
Jednak ty komentáře kompilátor nekontroluje a pak ani není nikde specifikované přesné chování programů v některých situacích - viz Rust Reference:
There is no formal model of Rust’s semantics for what is and is not allowed in unsafe code, so there may be more behavior considered unsafe.
Což chápu tak, že to, co je dnes v pořádku, může být zítra nedefinované chování.
> Co znamená „těžší“?
Že člověk musí hlídat víc věcí sám. Zvlášť pokud se rozhodne použít reference a ukazatele dohromady - což se občas dělá, když například chcete vystavit safe rozhraní s referencemi.
V unsafe například snadno převedete ukazatel na mut referenci, i když už někde jinde existuje jiná reference - a existence mut reference a jiné reference může být nedefinované chování.
Nebo pokud pracuje pouze s ukazateli, tak si musí hlídat, aby se omylem neuvolnilo něco, s čím pracuje - protože na rozdíl od C bývá volání drop implicitní. Takže se pak použije třeba Box::leak a pak se to zase musí ve vhodný moment uvolnit.
Před několika měsíci jsem zkoušel přepsat B-strom ze standardní knihovny Rustu do C3 (takové lepší C) a node.rs z Rustu, který měl 1800 řádků, se smrskl na node.c3 se 700 řádky. Algoritmus zůstal stejný, ale nebylo potřeba řešit aliasing referencí nebo převody ukazatelů na reference a naopak.
> Z mé zkušenosti je výrazně těžší psát unsafe kód v Rustu
Ano je to někdy těžší a překladač pochopitelně ty komentáře nekontroluje. Ale peer-review ano. S aliasingem máte pravdu. Naštěstí je cílem mít těch unsafe co nejméně a mít je zapouzdřené, že ano. Většina kódu je téměř vždy logika, která už může počítat se safe chováním.
V C je méně magie, ale taky naprosto žádná kontrola. Use after free a SIGSEGV jsou tak běžné problémy, že ta trocha komplikací za to stojí.
Výrazně lépe se mi upravuje safe Rust kód než C a C++(11). Prostě mám lepší přehled o vazbách a vlastnictví entit. V unsafe.. no naštěstí do něj nemusím sahat tak často.
> Což chápu tak, že to, co je dnes v pořádku, může být zítra nedefinované chování.
Což jsem zažil i v C++ (nepřímo, bug report na gcc co řešili kolegové). V C je toho minimum, ale tuhle diskuzi jsme už před nějakou dobou vedli - signed typy atd.
Byly doby kdy jsem si myslel ze neni mozne nahradit Perl. Perl mel obrovsky mnostvi knihoven, na CPANu jste mohli najit reseni na cokoliv jste si vzpomeli.
A pak prisly vyvojovy nastroje jako je treba PyCharm a v Pythonu se programuje s takovou lehkosti, ze Python ten naskok Perl-u velice rychle dohnal.
> V čem je C nenahraditelný?
Oproti Rustu je snazší být s C více nezávislý. Třeba na kompilátoru nebo na standardní knihovně.
(1) Například napsat náhradu standardní knihovny v C je celkem jednoduché, ale v Rustu je to extrémně složité, protože se nevyhnete unsafe, který je v Rustu bohužel složitější než v C. (2) Nebo pokud chcete mít vlastní kompilátor nebo kompilátor s vlastními rozšířeními - to je opět jednodušší pro C.
> C++ v podstatě nahradil C a nyní rust nahrazuje C++.
Někteří lidé přepsali projekty z C++ do C. Já jsem se kdysi také začal učit napřed C++ a pak jsem přešel k C.
Hlavní problém C je, že je IMO málo dobrých zdrojů, jak v něm programovat.
C v podpore MCU platforem. Jestli se nepletu, tak Rust z tohoto segmentu podporuje ARM Cortex M (to je fajn), MSP430 a mozna i trosku AVR (to je nejakej fork?). Jenze ta oblast nasazeni MCU je mnohem mnohem vetsi.
To ze C++ v podstate nahradil C - citation needed. Tiobe to neukazuje a jiny metriky kupodivu nerozlisuji C od C++ (a to tedy nechapu, ty jazyky uz se hodne rozesly).
AVR už dávno není fork.
https://doc.rust-lang.org/nightly/rustc/platform-support/avr-none.html (Tier 3 support)
Nightly + https://github.com/Rahix/avr-hal (ono je nightly dost užitečné i pro ten ARM).
V tom seznamu https://doc.rust-lang.org/nightly/rustc/platform-support.html je hodně platforem. Včetně mips, RiscV a dalších.
Pry je spousta paralelnich vesmiru ktere se lisi jen nejakou malickosti. V tomhle pripade to je videt na vete "Až později je napadlo všechno přepsat z C do C++, aby všechen kód aplikace vypadal hezky C++kově."
V mem vesmiru nikoho nenapadlo "všechno přepsat" a prevazna vetsina zustala v C (napr. vcetne linux kernelu).
Linux kernel je C, takže těžko v něm bude něco v C++. Mám na mysli, třeba že se i v C++ používal <pthread.h>, až o desítky let později (C++ 11) vzniklo <thread>.
Je to podobné, jakože Firefox měl rozšíření Firebug, ostatní prohlížeče přišli s integrovaným vývojářským nástrojem a až roky po nich Firefox taky vytvořil vlastní vývojářský panel.
2. 9. 2025, 13:51 editováno autorem komentáře
Ja vlastne reagoval spis na obecnou vetu "C++ v podstatě nahradil C" o uroven vys. A i vas prispevek byl hodne obecny a pochopil jsem ho obecne, ale asi tim byl myslen pouze nejaky jeden konkretni projekt ktery se povedlo po cca 30 letech prepsat z mixu c/c++ do 'hezkeho' c++.
Tim Firebugem se to nakonec vsechno vysvetlilo, proste vozova hradba :-)
A mimochodem o pouziti c++ v linux kernelu se vedly vazne diskuze, bohudik to tehdy v tom nasem vesmiru nedopadlo podle myslenek v tehle diskuzi takze zustalo C. Ale ted jede druhe kolo s Rustem.