Je jazyk C skutočne ťažký?

Re:Je jazyk C skutočne ťažký?
« Odpověď #150 kdy: 10. 06. 2025, 22:43:38 »
Vyumelkovany proto, ze se cela diskuze toci jenom kolem jednoho undefined signed arithmetic shiftu. O nejakem podelanem shiftu ten jazyk vubec neni.
Jop, C není o jednom podělaném shiftu.

Ale tahle diskuze je o tom jestli je C těžké. A to, že tu můžeme takhle složitě rozebírat chování jednoho podělaného shiftu, tu obtížnost ilustruje naprosto dokonale.

OT: ciste na zaklade tohoto operatoru jde naprosto to stejny rict o Jave, kde zrovna shifty taky pekne ohnuli, takze je to plny prekvapeni.


Re:Je jazyk C skutočne ťažký?
« Odpověď #151 kdy: 11. 06. 2025, 01:05:36 »

OT: ciste na zaklade tohoto operatoru...


Nejde iba o jeden operátor. Hlavný problém je to, že ľudia nechápu, čo je to nedefinované správanie, prečo existuje, čo spôsobuje a kam až siahajú jeho účinky.

A z toho potom niekedy vznikajú situácie, keď je program z dôvodu nedefinovaného správania neplatný, ale zdá sa, že funguje.

Re:Je jazyk C skutočne ťažký?
« Odpověď #152 kdy: 11. 06. 2025, 01:45:58 »
Nejde iba o jeden operátor. Hlavný problém je to, že ľudia nechápu, čo je to nedefinované správanie, prečo existuje, čo spôsobuje a kam až siahajú jeho účinky.
Ono existuje? UB se přece nikdy neděje. Ty jako programátor ses o to přece postaral a překladač ti v tom bezmezně věří.  8)

Občas mám pocit, že samotná slova jako "chování", "způsobuje" a podobné zastírají podstatu UB a proč je to občas takový mindfuck. Ta představa, že to UB něco dělá, je svým způsobem strašně špatně.

Re:Je jazyk C skutočne ťažký?
« Odpověď #153 kdy: 11. 06. 2025, 07:15:44 »
To, co tu tvrdíme už nějakou dobu. Nechat C jen tam, kde je to nezbytně nutné. A tam, kde chceš performance, ale není nutně důvod použít C, použít třeba Rust. Který dá +- podobný výkon, ale z principu vyloučí velmi časté chyby z C.

Proč lidi tolik trvají na tom, že i šroub musí zatlouct kladivem, jen proto, že je to o něco rychlejší, než najít ten šroubovák?  :D

Ono psát nějaké datové struktury v Rustu je celkem chuťovka. Ve standardní knihovně se k tomu používá unsafe Rust a opět vám hrozí nedefinované chování kvůli aliasingu. Navíc řešíte řešíte problémy, které v C nejsou, jako například, jak vhodně použít PhantomData.

Re:Je jazyk C skutočne ťažký?
« Odpověď #154 kdy: 11. 06. 2025, 08:20:02 »
To, co tu tvrdíme už nějakou dobu. Nechat C jen tam, kde je to nezbytně nutné. A tam, kde chceš performance, ale není nutně důvod použít C, použít třeba Rust. Který dá +- podobný výkon, ale z principu vyloučí velmi časté chyby z C.

Proč lidi tolik trvají na tom, že i šroub musí zatlouct kladivem, jen proto, že je to o něco rychlejší, než najít ten šroubovák?  :D

Ono psát nějaké datové struktury v Rustu je celkem chuťovka. Ve standardní knihovně se k tomu používá unsafe Rust a opět vám hrozí nedefinované chování kvůli aliasingu. Navíc řešíte řešíte problémy, které v C nejsou, jako například, jak vhodně použít PhantomData.


Protože ty problémy v C jsou. Schované. Rust Vás jen donutí je explicitně pojmenovat a vyřešit.


Tady prezentovaná zásadní výhoda C - výkon a přímé napojení na hw - je i jeho zásadní nevýhodou. Překladač nemá dost informací o vysokoúrovňovém záměru a nemůže tudíž aplikovat všechny optimalizace a kontroly.


Re:Je jazyk C skutočne ťažký?
« Odpověď #155 kdy: 11. 06. 2025, 08:25:06 »

Ono existuje? UB se přece nikdy neděje. Ty jako programátor ses o to přece postaral a překladač ti v tom bezmezně věří.  8)

Občas mám pocit, že samotná slova jako "chování", "způsobuje" a podobné zastírají podstatu UB a proč je to občas takový mindfuck. Ta představa, že to UB něco dělá, je svým způsobem strašně špatně.

To už celkom preháňate, nemyslíte? Alebo je to tak, že by ste si to mali do študovať?

jjrsk

  • *****
  • 772
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #156 kdy: 11. 06. 2025, 08:38:08 »
...Rust Vás jen donutí je explicitně pojmenovat a vyřešit.
Jo tak proto to pri kompilaci sebe sama hlasi kazdej jeden radek kodu ze je vadnej ... teda nez ta kompilace zbuchne, protoze to samosebe zkopilovat neumi.

Zjevne kvalitka ....

Re:Je jazyk C skutočne ťažký?
« Odpověď #157 kdy: 11. 06. 2025, 08:43:39 »
Tady prezentovaná zásadní výhoda C - výkon a přímé napojení na hw - je i jeho zásadní nevýhodou. Překladač nemá dost informací o vysokoúrovňovém záměru a nemůže tudíž aplikovat všechny optimalizace a kontroly.
S tím přímým napojením na hw je to taky zajímavé. Ono je to spíš nadstandardní rozšíření různých dialektů, než něco ze standardního C.

Standardní C vám dlouho nedalo ani add with carry.
A díky strict aliasingu je v něm prakticky neimplementovatelné třeba rychlé memcpy.


Ono existuje? UB se přece nikdy neděje. Ty jako programátor ses o to přece postaral a překladač ti v tom bezmezně věří.  8)

Občas mám pocit, že samotná slova jako "chování", "způsobuje" a podobné zastírají podstatu UB a proč je to občas takový mindfuck. Ta představa, že to UB něco dělá, je svým způsobem strašně špatně.

To už celkom preháňate, nemyslíte? Alebo je to tak, že by ste si to mali do študovať?
Proč přeháním? UB stojí na tom, že nesmí nastat. Validní C programy neobsahují UB. Programátor má za úkol zajistit aby k němu nemohlo dojít.
Dereference NULL je UB -> když dereferencuju pointer, tak optimalizátor ví, že nikdy nemůže být NULL a může tuhle informaci využít jak uzná za vhodné.
Nebo třeba funkce
Kód: [Vybrat]
bool test(int x)
{
  return x+1 > x
}
říká dvě věci :
1) + nikdy nepřeteče, takže test vždycky vrátí true. Takže z toho může optimalizátor udělat return true.
2) x nikdy nebude INT_MAX (protože by + přeteklo). Takže optimalizátor může tuhle informaci propagovat výš. Občas to může dotéct až překvapivě daleko.

Jen jsem se snažil trošku nezvyklým způsobem vystihnout tu neintuitivnost celého UB.
« Poslední změna: 11. 06. 2025, 08:49:04 od Jiří Havel »

Re:Je jazyk C skutočne ťažký?
« Odpověď #158 kdy: 11. 06. 2025, 08:45:45 »
A hádáte se zbytečně. C totiž je těžké. Nejde jen o různé pasti s undefined behavior. Popravdě jste tu zatím všechny ukázky založili na jediné oblasti, čísla se znaménkem.

Hlavní důvod proč je C těžké, je neexistence knihovny standardních datových struktur a masivní použití (často netypovaných void) pointerů.

- C nemá strukturu pro asociativní pole (ať už hash nebo strom)
- C neumí pohlídat přetečení bufferu
- C neumí pohlídat use-after-free

Takže aby programátor neudělal logickou chybu, musí držet v hlavě celý datový model aplikace a vědět, komu patří který pointer, kdo je zodpovědný za uvolnění atd.

Proto vznikají články jako už zmíněný https://floooh.github.io/2018/06/17/handles-vs-pointers.html , proto máme valgrind (a taky glib nebo Qt/QML pro C++).

Ano, možnost toto všechno řídit ručně umožní vyždímat i poslední kousek výkonu. Tedy možná, protože dnešní procesory jsou tak složité, že optimalizace programátorem naopak stav často zhorší.

Naprostá většina aplikací toto nepotřebuje. Naprostá většina aplikací potřebuje spolehlivou logiku a datový model víc, než optimalizaci na HPC nebo absolutně nejnižší možnou latenci.

C je jen o malý schůdek nad assemblerem. A kolik kódu jste za poslední dekádu napsali v ASM? Obojí se hodí, až když uděláte profiling a zjistíte, že Vás opravdu omezuje funkce na násobení matice nebo něco podobného (https://www.laws-of-software.com/laws/knuth/ ).

Ale na zbytek aplikace je mnohem vhodnější použít něco, kde se můžete soustředit na to CO to má dělat místo na to, JAK to je implementované na nízké úrovni.

C++ má spoustu podobných pastí, ale alespoň má STL, takže máte smart pointery a nemusíte si psát věci jako Vector nebo iterátory pořád dokola. Rust zase vyžaduje pochopení lifetimes pro jakoukoliv složitější strukturu a je přísný při překladu.

Re:Je jazyk C skutočne ťažký?
« Odpověď #159 kdy: 11. 06. 2025, 08:52:26 »
...Rust Vás jen donutí je explicitně pojmenovat a vyřešit.
Jo tak proto to pri kompilaci sebe sama hlasi kazdej jeden radek kodu ze je vadnej ... teda nez ta kompilace zbuchne, protoze to samosebe zkopilovat neumi.

Zjevne kvalitka ....

Protože bootstraping překladače je něco, co děláme všichni každý den. Bootstraping gcc jsem dělal přesně dvakrát v životě. A taky to vyžadovalo binárky, pak statický build a pak teprve finální build s optimalizacemi a knihovnami.

A Rust navíc má zdokumentované proč to tak je. Kompilujete překladač s kódem, který teprve bude stabilní (v té nové verzi). Jelikož to Rust hlídá, tak to za normálních okolností nedovolí. Proto je tam pro bootstrap speciální proměnná, která ty nightly-only kontroly vypne.

https://rustc-dev-guide.rust-lang.org/building/bootstrapping/what-bootstrapping-does.html#complications-of-bootstrapping

Ink

  • *****
  • 684
    • Zobrazit profil
    • E-mail
Re:Je jazyk C skutočne ťažký?
« Odpověď #160 kdy: 11. 06. 2025, 08:53:32 »
...Rust Vás jen donutí je explicitně pojmenovat a vyřešit.
Jo tak proto to pri kompilaci sebe sama hlasi kazdej jeden radek kodu ze je vadnej ... teda nez ta kompilace zbuchne, protoze to samosebe zkopilovat neumi.

Zjevne kvalitka ....

Kam chceš tímto příspěvkem posunout debatu?

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #161 kdy: 11. 06. 2025, 09:11:33 »
To, co tu tvrdíme už nějakou dobu. Nechat C jen tam, kde je to nezbytně nutné. A tam, kde chceš performance, ale není nutně důvod použít C, použít třeba Rust. Který dá +- podobný výkon, ale z principu vyloučí velmi časté chyby z C.

Proč lidi tolik trvají na tom, že i šroub musí zatlouct kladivem, jen proto, že je to o něco rychlejší, než najít ten šroubovák?  :D

Ono psát nějaké datové struktury v Rustu je celkem chuťovka. Ve standardní knihovně se k tomu používá unsafe Rust a opět vám hrozí nedefinované chování kvůli aliasingu. Navíc řešíte řešíte problémy, které v C nejsou, jako například, jak vhodně použít PhantomData.


Protože ty problémy v C jsou. Schované. Rust Vás jen donutí je explicitně pojmenovat a vyřešit.


Tady prezentovaná zásadní výhoda C - výkon a přímé napojení na hw - je i jeho zásadní nevýhodou. Překladač nemá dost informací o vysokoúrovňovém záměru a nemůže tudíž aplikovat všechny optimalizace a kontroly.

Praveze C umoznuje psat tak ci onak. Je to o tom jak si programator projekt zorganizuje.

Re:Je jazyk C skutočne ťažký?
« Odpověď #162 kdy: 11. 06. 2025, 09:43:40 »
Praveze C umoznuje psat tak ci onak. Je to o tom jak si programator projekt zorganizuje.

Programátor si může přidat komentáře a rozdělit soubory. Jenže překladač z toho tu sémantiku nepozná. Neví jaký je záměr. V Rustu můžeme (no spíš musíme) překladači říct, jak dlouho daný pointer žije. V C++ existuje alespoň unique_ptr / shared_ptr. V C to u pointeru není jak vyjádřit.

Což omezuje možnosti automatické analýzy a optimalizace. Takže to musí hlídat programátor a tím dochází k chybám, protože lidi dělají chyby.

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #163 kdy: 11. 06. 2025, 09:49:34 »
Proč přeháním? UB stojí na tom, že nesmí nastat. Validní C programy neobsahují UB. Programátor má za úkol zajistit aby k němu nemohlo dojít.
Dereference NULL je UB -> když dereferencuju pointer, tak optimalizátor ví, že nikdy nemůže být NULL a může tuhle informaci využít jak uzná za vhodné.
Nebo třeba funkce
Kód: [Vybrat]
bool test(int x)
{
  return x+1 > x
}
říká dvě věci :
1) + nikdy nepřeteče, takže test vždycky vrátí true. Takže z toho může optimalizátor udělat return true.
2) x nikdy nebude INT_MAX (protože by + přeteklo). Takže optimalizátor může tuhle informaci propagovat výš. Občas to může dotéct až překvapivě daleko.

Jen jsem se snažil trošku nezvyklým způsobem vystihnout tu neintuitivnost celého UB.

A jak zapíšu do registru který je na adrese 0x00000000, nebo jak si přečtu kam ukazuje reset vektor, kdyby mi to kompilátor nedovolil? Proč by mi to neměl dovolit?

Kód: [Vybrat]
bool test(int x)
{
  return x+1 > x;
}
Při x == INT_MAX výsledek přeteče a je to UB.

Správný postup je nedovolit přetečení a ohandlovat ho:
Kód: [Vybrat]
bool test(int x)
{
  return x < INT_MAX ? x + 1 > x : false; // nebo true? Co ja vim jak tento dalsi vyumelkovany nesmysl ma vypadat...
}

Re:Je jazyk C skutočne ťažký?
« Odpověď #164 kdy: 11. 06. 2025, 10:18:58 »
A jak zapíšu do registru který je na adrese 0x00000000, nebo jak si přečtu kam ukazuje reset vektor, kdyby mi to kompilátor nedovolil? Proč by mi to neměl dovolit?
No blbě. Pokud to vaše platforma potřebuje, tak vám musí dát nějaký nestandardní způsob jak to udělat. Standardní C to neumí (pokud teda NULL odpovídá adrese 0, to taky nemusí platit).
Citace
Správný postup je nedovolit přetečení a ohandlovat ho:
Správný postup je napsat všechno bez chyb. Jenže my lidi to jaksi neumíme. A proto tu řešíme co mi jazyk udělá, když se seknu a něco neohandlím.