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

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #120 kdy: 10. 06. 2025, 13:15:54 »
Vědět, že je operátor >> implementation defined (většina lidí to neví a předpokládá, že se jedná o aritmetický shift).

Já jsem převážně používal bitové posuny na různé maskování a bitové operace a tam jsem logicky volil unsigned formát protože proč bych to měl mít signed když nepotřebuji záporná čísla.

Dále jsem používal pro rychlé násobení a dělení mocninama dvou a tam jsem vždy taky operoval raději na unsigned číslech, protože vím že záporná čísla mají nejvyšší bit vždy nahozen a tak logicky přichází otázka: co když zrotuju doleva a nahodí se nejvyšší bit - číslo se stane záporné - to bych nechtěl. Nebo co když zrotuju doprava a číslo ztratí svoje znaménko. Prostě bitové operace jsou low level operace a timpádem člověk musí vědět jak to dole skutečně vypadá.

Pokud si někdo klade stejné otázky, tak se taky automaticky raději vyhne jakýmkoliv bitovým operacím na signed číslech. A pokud ne, tak to je buď naivka a nebo expert který přesně ví co dělá. Jak říkal tady kolega - člověk by neměl předpokládat nic, měl by vše alespoň jednou v životě přečíst v dokumentaci. Programovat na základě předpokladů je dobrý hazard a doufám že to tak dělají jenom vyjímky a není to nový standard.


Re:Je jazyk C skutočne ťažký?
« Odpověď #121 kdy: 10. 06. 2025, 14:19:56 »
Navíc z mé praxe - nikdy jsem na to nenarazil, je to vyumělkovaný příklad.
To je argument jak noha. Nikdy jsem na to nenarazil, takže je to vyumělkovaný příklad... Dá se to napsat i jinak, nikdy jsem na to nenarazil, protože mám málo zkušeností, nebo jsem to prostě ve své praxi nikdy nepotřeboval. Extrapolovat, že je to vyumělkovaný příklad, je tak trochu nezkušenost.

Abych tě trochu uvedl do praxe, aritmetický posun vpravo se hodí k rychlému dělení signed integerů. Instrukci integer dělení nechceš, je na všech současných CPU podstatně dražší. Operátor dělení v C taky nechceš, protože dává jiné výsledky než aritmetický shift a překladač to musí handlovat, i když dělení optimalizuje na aritmetický shift.

Pokud mám náhodou implementaci C, která místo aritmetického shiftu dělá logický (což norma povoluje), musím do assembleru, protože C implementace aritmetického posunu bude pomalejší než instrukce CPU (pokud překladač nepozná, že dělám aritmetický posun a nezoptimalizuje to, což ale není zaručeno).

Wasper

  • ***
  • 177
    • Zobrazit profil
    • E-mail
Re:Je jazyk C skutočne ťažký?
« Odpověď #122 kdy: 10. 06. 2025, 14:27:00 »
Děkuji, to je hezká ukázka, jak je C prakticky velmi špatně použitelné. Abych dokázal použít operátor >> v C správně, tak musím:

  • Vědět, že je operátor >> implementation defined (většina lidí to neví a předpokládá, že se jedná o aritmetický shift).
...
A to vše jen proto, že si C táhne v dnešní době naprosto nerelevantní dědictví, kdy nechce definovat operátor >> na signed integeru jako aritmetický shift. Nemá to žádný praktický smysl, protože aktuálně neexistuje relevantní CPU, které by nebyla instrukce pro aritmetický shift.
Jediny bod 1 je relevantni, je treba vedet, jak je neco definovano. To se obavam, ze je podminkou nutnou kdekoli, a pro kazdy jazyk existuji stranky a videa na tema vsech moznych a nemoznych chytaku.

Zbyle body se tykaji toho, ze norma rika "nelizej v zime zabradli", tak jak to udelat, aby presto clovek to zabradli oliznul a nedopadlo to spatne.
Navic se tam resi i optimalizace, coz uz jsme na uplne novem levelu proti "nevi, jak ten operator funguje".[/list]

Re:Je jazyk C skutočne ťažký?
« Odpověď #123 kdy: 10. 06. 2025, 14:27:47 »
Pak by si asi měli přečíst dokumentaci.
To je validní argument, je to v dokumentaci. Nicméně čtení dokumentace C (a její aplikace v praxi) připomíná procházku minovým polem. Je tam opravdu hodně undefined a implementation defined behavior. To je ten problém, na který se snažím poukázat. A možnosti zlepšení jsou, ale jaksi se neuplatňují. Např. u operátoru >> stačí zadefinovat, že je to aritmetický shift na signed integeru a všichni by měli život jednodušší. C++20 už to udělalo, C23 ne.

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #124 kdy: 10. 06. 2025, 15:19:11 »
Navíc z mé praxe - nikdy jsem na to nenarazil, je to vyumělkovaný příklad.
To je argument jak noha. Nikdy jsem na to nenarazil, takže je to vyumělkovaný příklad... Dá se to napsat i jinak, nikdy jsem na to nenarazil, protože mám málo zkušeností, nebo jsem to prostě ve své praxi nikdy nepotřeboval. Extrapolovat, že je to vyumělkovaný příklad, je tak trochu nezkušenost.

Abych tě trochu uvedl do praxe, aritmetický posun vpravo se hodí k rychlému dělení signed integerů. Instrukci integer dělení nechceš, je na všech současných CPU podstatně dražší. Operátor dělení v C taky nechceš, protože dává jiné výsledky než aritmetický shift a překladač to musí handlovat, i když dělení optimalizuje na aritmetický shift.

Pokud mám náhodou implementaci C, která místo aritmetického shiftu dělá logický (což norma povoluje), musím do assembleru, protože C implementace aritmetického posunu bude pomalejší než instrukce CPU (pokud překladač nepozná, že dělám aritmetický posun a nezoptimalizuje to, což ale není zaručeno).

Heh naopak jsem mel dost zkusenosti na to, ze jsem si uvedomil ze to je implementation defined, protoze reprezentace signed cisel v C vzdy byla (az po C23) implementation defined a radeji tedy operoval na unsigned variante (jak jsem psal).

Lol - uvedl me do praxe :D Ja mam v C embedded programovani praxi 17 let.

Vyumelkovany proto, ze se cela diskuze toci jenom kolem jednoho undefined signed arithmetic shiftu. O nejakem podelanem shiftu ten jazyk vubec neni.
« Poslední změna: 10. 06. 2025, 15:22:06 od vrit »


Re:Je jazyk C skutočne ťažký?
« Odpověď #125 kdy: 10. 06. 2025, 15:25:35 »
Vědět, že je operátor >> implementation defined (většina lidí to neví a předpokládá, že se jedná o aritmetický shift).

Pak by si asi měli přečíst dokumentaci. Stejně tak by někdo mohl říct, že v Rustu většina lidí neví, že chování + závisí na tom, jestli kompilujete Debug nebo Release. Nebo v C#, že se chování ToUpper a ToLower řídí aktuálním locale a někdy můžete dostat fakt nečekané výsledky. Nebo v Gleamu, dělení 0 vrací 0, není to chyba. A takových situací jsou hromady ať už jste v Rustu, C, C++, Go nebo F#. Je lepší nepředpokládat a přečíst si dokumentaci.

Přesně tak. Znalost jazyka je nutná pro každý jazyk. A řeči typu "jazyk neděla co chci" = jen lenost si ho nastudovat. Každý jazyk se musí nastudovat, i ty moderní. Jestli to je někomu bližší, a snažší uchopit, tak budiž, ale ve výsledku je potřeba to nastudovat a tomu se člověk nevyhne ani v tom Rustu, ani C#. Každý jazyk má svá specifika a toto jsou dobré příklady že i v jiných jazycích se lze lehce střelit do nohy.
Pamatuju si, že velice podobnou argumentaci jsem četl i v diskuzi pod jedním legendárním Javascriptovým WTF. Tam se potkaly cca 3 perfektně zdokumentované konverze a výsledkem byl totálně nepochopitelný mindfuck.  8)

A proto máme i věci jako "princip minimálního překvapení", protože každá drobnost kterou neodhadneme a musíme ji nastudovat z dokumentace nám bere čas a mentální kapacitu.

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #126 kdy: 10. 06. 2025, 15:27:20 »
Pokud mám náhodou implementaci C, která místo aritmetického shiftu dělá logický (což norma povoluje), musím do assembleru, protože C implementace aritmetického posunu bude pomalejší než instrukce CPU (pokud překladač nepozná, že dělám aritmetický posun a nezoptimalizuje to, což ale není zaručeno).

Pokud překladač něco nedělá, a mermomocí to tam chceš, tak vždy musíš do assembleru, čímž ale ztrácíš portabilitu žejo. To se netýka jenom arithmetic shiftu, ale čehokoliv. V dokumentaci je, že je to implementation specific, takže když někdo očekává že to tam bude, tak je to naivka. Tohle mi příjde argument jak noha...

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #127 kdy: 10. 06. 2025, 15:29:10 »
Vědět, že je operátor >> implementation defined (většina lidí to neví a předpokládá, že se jedná o aritmetický shift).

Pak by si asi měli přečíst dokumentaci. Stejně tak by někdo mohl říct, že v Rustu většina lidí neví, že chování + závisí na tom, jestli kompilujete Debug nebo Release. Nebo v C#, že se chování ToUpper a ToLower řídí aktuálním locale a někdy můžete dostat fakt nečekané výsledky. Nebo v Gleamu, dělení 0 vrací 0, není to chyba. A takových situací jsou hromady ať už jste v Rustu, C, C++, Go nebo F#. Je lepší nepředpokládat a přečíst si dokumentaci.

Přesně tak. Znalost jazyka je nutná pro každý jazyk. A řeči typu "jazyk neděla co chci" = jen lenost si ho nastudovat. Každý jazyk se musí nastudovat, i ty moderní. Jestli to je někomu bližší, a snažší uchopit, tak budiž, ale ve výsledku je potřeba to nastudovat a tomu se člověk nevyhne ani v tom Rustu, ani C#. Každý jazyk má svá specifika a toto jsou dobré příklady že i v jiných jazycích se lze lehce střelit do nohy.
Pamatuju si, že velice podobnou argumentaci jsem četl i v diskuzi pod jedním legendárním Javascriptovým WTF. Tam se potkaly cca 3 perfektně zdokumentované konverze a výsledkem byl totálně nepochopitelný mindfuck.  8)

A proto máme i věci jako "princip minimálního překvapení", protože každá drobnost kterou neodhadneme a musíme ji nastudovat z dokumentace nám bere čas a mentální kapacitu.

princip minimálního překvapení je v C plně implementován a jmenuje se unsigned int - ten jsem ve své praxi vždy použil a nikdy jsem překvapen nebyl

Re:Je jazyk C skutočne ťažký?
« Odpověď #128 kdy: 10. 06. 2025, 15:33:00 »
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.

Re:Je jazyk C skutočne ťažký?
« Odpověď #129 kdy: 10. 06. 2025, 15:35:32 »
Heh naopak jsem mel dost zkusenosti na to, ze jsem si uvedomil ze to je implementation defined

Dovol, abych ti připomenul tohle:
C zachovava pri rotaci znamenko protoze rotace je provadena na znamenkovem typu, dela tedy tzv. aritmeticky bit shift.

Lol - uvedl me do praxe :D Ja mam v C embedded programovani praxi 17 let.
Tak je 17 let asi málo, ještě minulý týden jsi žil v domění, že je to arimetický shift a ne implementation defined. Jsem rád, že jsem ti pomohl rozšířit znalosti C. Není zač.

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #130 kdy: 10. 06. 2025, 15:42:21 »
Heh naopak jsem mel dost zkusenosti na to, ze jsem si uvedomil ze to je implementation defined

Dovol, abych ti připomenul tohle:
C zachovava pri rotaci znamenko protoze rotace je provadena na znamenkovem typu, dela tedy tzv. aritmeticky bit shift.

Jedine v cem js mi rozsiril znalosti je ze Cěš enforcuje dvojkovy doplnek, zato diky. Zbytek jsi mne spise nepochopil. Jinak o tve neustale utoky nestojim tak si je muzes smerovat jinam, diky :-) Arrogant prick...

Lol - uvedl me do praxe :D Ja mam v C embedded programovani praxi 17 let.
Tak je 17 let asi málo, ještě minulý týden jsi žil v domění, že je to arimetický shift a ne implementation defined. Jsem rád, že jsem ti pomohl rozšířit znalosti C. Není zač.

Jedine o cos mi rozsiril znalosti je ze C23 enforcuje dvojkovy doplnek. Za to diky. Zbytek bych spise rekl ze jsi mne nepochopil, nebo je taky mozne ze jsem se ve spechu nekde spatne vyjadril. Ale jinak o tve neustale utoky v diskuzi nestojim a muzes si je smerovat jinam, diky :-) Arrogant prick...
« Poslední změna: 10. 06. 2025, 15:45:26 od vrit »

Re:Je jazyk C skutočne ťažký?
« Odpověď #131 kdy: 10. 06. 2025, 15:59:20 »
Jedine o cos mi rozsiril znalosti je ze C23 enforcuje dvojkovy doplnek. Za to diky. Zbytek bych spise rekl ze jsi mne nepochopil, nebo je taky mozne ze jsem se ve spechu nekde spatne vyjadril. Ale jinak o tve neustale utoky v diskuzi nestojim a muzes si je smerovat jinam, diky :-) Arrogant prick...
Hele, já na tebe neútočím. Měli jsme nejasnosti ohledně chování operátoru >> v C a vysvětlili jsme si, že je to implementation defined. Měli jsme nejasnosti ohledně reprezentace signed čísel v C23 a vysvětlili jsme si, že to musí být druhý doplněk. Což já považuji za skvělou příležitost redefinovat chování operátoru >> jako arithmetic shift, přesně jak se stalo v C++20. Standardizační komise C23 a ty tento názor bohužel nesdílí, nedá si nic dělat, budeme muset dál žít s implementation defined.

Re:Je jazyk C skutočne ťažký?
« Odpověď #132 kdy: 10. 06. 2025, 16:05:08 »
princip minimálního překvapení je v C plně implementován a jmenuje se unsigned int - ten jsem ve své praxi vždy použil a nikdy jsem překvapen nebyl
Kód: [Vybrat]
unsigned x = 1;
if ( x < -1 )
  printf( "Co se sakra děje?" );
Unsigned v C(++) má vestavěné tak zákeřné překvápko, že je v některých mission critical systémech kompletně zakázaný. :)

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #133 kdy: 10. 06. 2025, 16:34:58 »
princip minimálního překvapení je v C plně implementován a jmenuje se unsigned int - ten jsem ve své praxi vždy použil a nikdy jsem překvapen nebyl
Kód: [Vybrat]
unsigned x = 1;
if ( x < -1 )
  printf( "Co se sakra děje?" );
Unsigned v C(++) má vestavěné tak zákeřné překvápko, že je v některých mission critical systémech kompletně zakázaný. :)

A kde je jaké překvápko? Překvapen může být akorát zase jenom ten kdo něco předpokládá. Ten kdo zná pořadí operátorů a implicitní konverze datových typů tak v tom má jasno.

Jinak tady není důvod aby to překladač nepodchytil:
Citace
547818386/source.c:6:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if ( x < -1 )
            ^

Re:Je jazyk C skutočne ťažký?
« Odpověď #134 kdy: 10. 06. 2025, 16:42:53 »
princip minimálního překvapení je v C plně implementován a jmenuje se unsigned int - ten jsem ve své praxi vždy použil a nikdy jsem překvapen nebyl
Kód: [Vybrat]
unsigned x = 1;
if ( x < -1 )
  printf( "Co se sakra děje?" );
Unsigned v C(++) má vestavěné tak zákeřné překvápko, že je v některých mission critical systémech kompletně zakázaný. :)

A kde je jaké překvápko? Překvapen může být akorát zase jenom ten kdo něco předpokládá. Ten kdo zná pořadí operátorů a implicitní konverze datových typů tak v tom má jasno.
A ještě si musí všimnout, že se mu signed a unsigned potkaly. Stačí aby to x nebylo deklarované hned vedle toho ifu a je to.
Citace
Jinak tady není důvod aby to překladač nepodchytil:
Citace
547818386/source.c:6:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if ( x < -1 )
            ^
Nějaký důvod tam bude, když MSVC i clang mlčí jak partizáni. A i gcc potřebuje -Wall, jinak drží hubu.

U jiných věcí mi překladače nadávají daleko ochotněji. Tenhle warning z nich člověk musí spíš páčit.