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

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #60 kdy: 03. 06. 2025, 14:03:21 »
Protože unární -INT_MIN je overflow. Nevím, jak binární. Ale třeba při použití zig cc (když Zigem kompilujeme C), tak takový program spadne na nedefinované chování i s binárním operátorem. Nebo, když to přeložím starým CompCertem, tak ten vypíše varování integer literal '2147483648' is too large to be represented in the enumeration integer type.

Unarni minus, to neni nas pripad. Spadne kde a proc? Urcite na te instrukci pro odecet? Tak co ja vim co s tim zig cc udela... asi neni C compliant :D

Ohledne CompCertu me zrazi tato cast hlasky: to be represented in the enumeration integer type

Jaky enumeration integer type? Zadny enum nikde neni, tak nechapu proc by to neco takoveho melo psat...
Zadne upravy v kodu nejsou - kod je presne tak jak jsem poslal? A jak je to zavolano?
poprosil bych cely kod...


Re:Je jazyk C skutočne ťažký?
« Odpověď #61 kdy: 03. 06. 2025, 14:04:02 »
OT k těm bitovým a aritmetickým posunům. Ani jinde to není úplně růžové. Třeba Java je na jednu stranu mnohem specifičtější, ale posuny jsou omezeny na 31 resp. 32 bitů, což dokáže docela dobře zmást.

U céčka je situace jasná - musí běžet na čemkoli, od osmibitových MCU přes DSP až po 64bitové příšery. Takže spousta věcí je prostě závislá na architektuře.

Re:Je jazyk C skutočne ťažký?
« Odpověď #62 kdy: 03. 06. 2025, 14:04:18 »
Tak to ale prece neni zadny neprekonatelny problem... napises si na to inline funkci, ktera to dela tak jak chces (pomoci castu na unsigned integer)
Ale já nechci logical shift na unsigned integeru, chci arithmetic shift na signed integeru. Jak to udělám bezpečně v C? Neudělám, pokud si sám nenaimplementuji operaci arithmetic right shift. V ostatních jazycích to není problém, prostě použiju operátor >>, protože ve všech normálních jazycích je definované, že operátor >> dělá arithmetic right shift.

Re:Je jazyk C skutočne ťažký?
« Odpověď #63 kdy: 03. 06. 2025, 14:34:34 »
A co na to tazatel? Jak moc mu tohle přijde jednoduché? ;)

Tak co je uvnitr je podle me fuk, pro tazatele dulezite, ze takto to muze zavolat:

Kód: [Vybrat]
int result;
if(add_will_overflow(0x90000000, 0x900000000, &result))
{
    // handle overflow
}
Jenže zavolat ji může jen když ji má. Jak nemá C23 tak tuhle funkci mu napíše jen C expert. A i to aby vůbec věděl, kdy tuhle funkci bude potřebovat, je zapotřebí nepříjemně mnoho znalostí.
 
Jde mi o to, že v C má i jednoduché počítání s intama spoustu překvapení. Není to jen tohle nedefinované chování. Jsou to i sequence pointy. To, že asociativita operátorů neříká nic o pořadí v jakém se vyhodnocuje složitější výraz. a můžu pokračovat. Jak v assembleru tak ve vysokoúrovňových jazycích jsou inty podstatně jednodušší než v C.

Základní věci jsou zbytečně (z dnešního pohledu) komplikované a složitější tam nejsou vůbec.

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #64 kdy: 03. 06. 2025, 14:45:14 »
Ale já nechci logical shift na unsigned integeru, chci arithmetic shift na signed integeru. Jak to udělám bezpečně v C? Neudělám, pokud si sám nenaimplementuji operaci arithmetic right shift. V ostatních jazycích to není problém, prostě použiju operátor >>, protože ve všech normálních jazycích je definované, že operátor >> dělá arithmetic right shift.

A tvoje "normalni jazyky" umi bezet na procesorech ktere mohou mit tyto ruzne interpretace signed cisel?
Citace
Two's Complement
One's Complement
Sign and Magnitude
Offset Binary (Excess-K)
Binary Coded Decimal (BCD)
Base-2 Signed Digit (BSD)

Nebo treba na pocitaci s nebinarni logikou, jako sovetsky Setun?

Proste binarnich interpretaci signed cisel, a s tim souvisejici otazky jako "kde je znamenko" a "jestli tam vubec to znamenko je" neumoznuji udelat jednotny aritmeticky shift a proto je potreba si ho udelat rucne.

Podle me tvoje "normalni jazyky" toho jsou schopny jenom proto, ze se omezujou na architektury pouzivajici dvojkovy doplnek - cili nejsou prenositelne vsude. A nebo i v nich to musi byt implementation defined, akorat se o tom nemluvi...

Sice dvojkovy doplnek je univerzalni v tom smyslu ze kazdy procesor ktery umi unsigned aritmetiku umi i signed aritmetiku v dvojkovem doplnku - to je prave jeho vyhoda, ze pro procesor se nic nemeni oproti normalu. Ale je to SW reseni a nemusi byt treba tak optimalni jako HW reseni na dane platforme a proto C umoznuje oboji - umoznuje implementovat takovy, i onaky prekladac.


Re:Je jazyk C skutočne ťažký?
« Odpověď #65 kdy: 03. 06. 2025, 14:53:05 »
A tvoje "normalni jazyky" umi bezet na procesorech ktere mohou mit tyto ruzne interpretace signed cisel?
A potřebují to? Nebo jsou to jen zkamenělé pozůstatky muzejního hardwaru?

Vzhledem k tomu, že to nové normy vyrazily (v  rámci možností zpětné kompatibility), je odpověď celkem jasná.

Všechno tohle už je jen technický dluh, který dělá Cčko složitějším.

Ink

  • *****
  • 686
    • Zobrazit profil
    • E-mail
Re:Je jazyk C skutočne ťažký?
« Odpověď #66 kdy: 03. 06. 2025, 14:56:24 »
Podle me tvoje "normalni jazyky" toho jsou schopny jenom proto, ze se omezujou na architektury pouzivajici dvojkovy doplnek - cili nejsou prenositelne vsude. A nebo i v nich to musi byt implementation defined, akorat se o tom nemluvi...

Sice dvojkovy doplnek je univerzalni v tom smyslu ze kazdy procesor ktery umi unsigned aritmetiku umi i signed aritmetiku v dvojkovem doplnku - to je prave jeho vyhoda, ze pro procesor se nic nemeni oproti normalu. Ale je to SW reseni a nemusi byt treba tak optimalni jako HW reseni na dane platforme a proto C umoznuje oboji - umoznuje implementovat takovy, i onaky prekladac.

Upozorňuju na to, že v "normálních" jazycích (pokud jimi myslíme Rust a spol.) existuje často nějaký způsob, jak tyto speciální věci udělat, byť to nemusí nutně přes operátor:

https://doc.rust-lang.org/stable/std/primitive.isize.html

Re:Je jazyk C skutočne ťažký?
« Odpověď #67 kdy: 03. 06. 2025, 15:01:03 »
A tvoje "normalni jazyky" umi bezet na procesorech ktere mohou mit tyto ruzne interpretace signed cisel?
A které dnes relevantní CPU používají pro reprezentaci signed čísel něco jiného než two's complement? Odpovím ti, žádné. Rezignovalo na ně dokonce i C a v nové verzi C23 standardu nic jiného než two's complement pro reprezentaci signed čísel nedovoluje.

Takže tady máme naprosto nerelevantní historické dědictví, které přidává další velmi elegantní způsob, jak se v C střelit do nohy použitím operátoru >> na signed integeru, protože v C (včetně C23) je to stále implementation defined. Člověk by čekal, že by bylo rozumné alespoň v C23 definovat, že je to arithmetic right shift, ale bohužel se to nestalo. Nevím, co standardizační komise C23 dělá, asi je běžní uživatelé C nezajímají. V C++ to už pochopili a od C++20 je operátor >> na signed integeru vždy arithmetic right shift.

Takový přístup chceš obhajovat, opravu ti přijde rozumné mít right shift implementation defined, když i C++20 to jasně definovalo jako arithmetic right shift?

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #68 kdy: 03. 06. 2025, 15:08:35 »
Jenže zavolat ji může jen když ji má. Jak nemá C23 tak tuhle funkci mu napíše jen C expert. A i to aby vůbec věděl, kdy tuhle funkci bude potřebovat, je zapotřebí nepříjemně mnoho znalostí.
 
Jde mi o to, že v C má i jednoduché počítání s intama spoustu překvapení. Není to jen tohle nedefinované chování. Jsou to i sequence pointy. To, že asociativita operátorů neříká nic o pořadí v jakém se vyhodnocuje složitější výraz. a můžu pokračovat. Jak v assembleru tak ve vysokoúrovňových jazycích jsou inty podstatně jednodušší než v C.

Základní věci jsou zbytečně (z dnešního pohledu) komplikované a složitější tam nejsou vůbec.

Tak mit tu funkci, to je jen otazka toho mit danou knihovnu a nelisi se to nijak od napriklad pythoniho "import ..."
To uz je trochu polemika o tom co jeste ma a co uz nema byt soucasti standardu. Ale proc se omezovat na standard? Pokud je knihovna prenositelne napsana, tak muze byt pouzivana vsude a lze ji brat jako rozsireni standardu.

Knihovny by meli psat experti, novacek tam udela chyby, cili tady nevidim nic spatne - at pouzije knihovnu napsanou expertem, to je v poradku.

Kdy tuhle funkci bude potrebovat - tuto znalost musi mit ve vsech jazycich. Pokud se porad bavime o overflow jednointegerove promenne, tak ze je treba overflow ohandlovat - to je potreba vedet ve vsech jazycich. Kdyz to nebude vedet, neohandluje to ani v jinem jazyce.

Pokud chce clovek aby mu to vratilo inf pri overflow jako treba v Pythonu tak at si to naimplementuje - udela to jednou v zivote a pak uz to jen pouziva. Pokud prijme filozofii nekoho kdo uz toto vymyslel tak at pouziva jeho knihovnu. Nijak se to nelisi od prijeti filozofie jineho jazyka.

Pokud nechceme nikdy zadny overflow, tak na to uz jsem zminoval GMP knihovnu.

Neprijemne mnoho znalosti - proste kdo chce velkou kontrolu nad CPU, musi mit mnoho znalosti. Jestli je mu to neprijemne, tak to je jednoduche - at pouziva jiny jazyk :)

Respektuju nazor ale jsou to jenom subjektivni dojmy. Co je pro jednoho prekvapeni, muze byt pro jineho jasne logicky zaver.

Ja jsem se treba par let zpatky ucil C# a tak jak v C je mi vse jasne, tak C# mel pro me spoustu prekvapeni. Napriklad ze neco se predava hodnotou a neco referenci.

Proste C asi neni pro vsechny, ale to plati o vsem. Co je pro jednoho lehke, je pro jineho tezke.

Ale co bych doporucil tazatelovi je se ucit od nekoho kdo to zna - s nim konzultovat. Rict mu treba toto a toto mi prijde tezke, delam neco spatne, neda se to jinak? A zkuseny programator mu treba ukaze hned jak na to jednoduse.

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #69 kdy: 03. 06. 2025, 15:25:37 »
A které dnes relevantní CPU používají pro reprezentaci signed čísel něco jiného než two's complement? Odpovím ti, žádné. Rezignovalo na ně dokonce i C a v nové verzi C23 standardu nic jiného než two's complement pro reprezentaci signed čísel nedovoluje.

Takže tady máme naprosto nerelevantní historické dědictví, které přidává další velmi elegantní způsob, jak se v C střelit do nohy použitím operátoru >> na signed integeru, protože v C (včetně C23) je to stále implementation defined. Člověk by čekal, že by bylo rozumné alespoň v C23 definovat, že je to arithmetic right shift, ale bohužel se to nestalo. Nevím, co standardizační komise C23 dělá, asi je běžní uživatelé C nezajímají. V C++ to už pochopili a od C++20 je operátor >> na signed integeru vždy arithmetic right shift.

Takový přístup chceš obhajovat, opravu ti přijde rozumné mít right shift implementation defined, když i C++20 to jasně definovalo jako arithmetic right shift?

Co to je "dnes relevantni"? Pro C je relevantni KAZDY procesor, odtud PRENOSITELNOST. To ze pro tebe neco neni relevantni nikoho nezajima, natoz pak tvurce standardu :D

Hehe prave naopak, C23 si PONECHAL moznost jine reprezentace signed cisel a dukazem je ze arithmetic right shift je stale implementation defined.
Proste prenositelnost a vykon jsou hlavni rysy jazyka C, takze umozuje i prekladac ktery pouziva jinou intepretaci zapornych cisel, pokud to HW podporuje.
Jestli to je okrajova zalezitost nebo ne, to C neresi. C umoznuje oboje.

To vubec neni o tom jestli mi neco prijde rozumne nebo jestli ja chci neco objajovat. Ja rikam proc to tam je, ze to ma svuj duvod a jak si to kdo vylozi je mi celkem fuk :D

Ze se nekdo streli do nohy, tak to je proste jen jeho neznalost, co na to rict. Snad aby si vybral nejakou bezpecnejsi zbran :-)

BoneFlute

  • *****
  • 2 043
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #70 kdy: 03. 06. 2025, 15:35:38 »
Ze se nekdo streli do nohy, tak to je proste jen jeho neznalost, co na to rict. Snad aby si vybral nejakou bezpecnejsi zbran :-)

Já bych tomu třeba říkal polovičatost.

Re:Je jazyk C skutočne ťažký?
« Odpověď #71 kdy: 03. 06. 2025, 15:36:46 »
Hehe prave naopak, C23 si PONECHAL moznost jine reprezentace signed cisel a dukazem je ze arithmetic right shift je stale implementation defined.
Přestaň už prosím psát nesmysly. Toto bylo akceptováno do C23 a NEDOVOLUJE to použít pro reprezentaci signed čísel nic jiného, než two's complement. Ke zbytku se nebudu vyjadřovat.

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2412.pdf

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #72 kdy: 03. 06. 2025, 15:55:45 »
Já bych tomu třeba říkal polovičatost.
Zbrane nebo obsluhy? :)

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #73 kdy: 03. 06. 2025, 15:57:15 »
Přestaň už prosím psát nesmysly. Toto bylo akceptováno do C23 a NEDOVOLUJE to použít pro reprezentaci signed čísel nic jiného, než two's complement. Ke zbytku se nebudu vyjadřovat.

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2412.pdf

Oukej, my bad. Toto jsem nevedel. V tomto ti davam za pravdu. Ale v principu to co jsem rekl plati, jen teda ne pro aritmetiku, ale pro bit shift jako takovy - tam proste rozdily na urovni HW mohou byt a prekladac muze cilit na optimalizovanou HW variantu.
« Poslední změna: 03. 06. 2025, 15:59:06 od vrit »

BoneFlute

  • *****
  • 2 043
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #74 kdy: 03. 06. 2025, 16:57:13 »
Já bych tomu třeba říkal polovičatost.
Zbrane nebo obsluhy? :)

C začlo jako takový lepší Assembler. Takže je pochopitelné, že nebude aspirovat na nějaké úžasné záruky jako dnešní moderní sofistikované jazyky. To je cajk. Ale skutečnost, že nechává signed jako nedefinované mi přijde polovičaté. To máš stejné, jako kdyby byla nedefinovaná třeba konstrukce for jenom kůli tomu, že nějaký obskurní procesor nemá loopy. To není neznalost. To je jednoznačně  chyba na straně C. Nemá to zkoušet vůbec rozlišovat signed a unsigned, a pak bych to bral. Takhle říká, že si to bere na starost, a přitom kecá.