Programozási versenyfelhívás

Elegem lett a sok nagyszájúból, ezért úgy döntöttem, lehetőséget adok nektek a gyakorlatban is bizonyítani, és egy versenyre hívlak ki Titeket!

Amennyiben nem érkezne egyetlen működőképes beadvány sem, vagy a C nyerne, akkor azt úgy kell érteni, hogy valójában a gyakorlatban egyik csodanyelv sem képes leváltani a C-t, és továbbiakban nem hangoztathatjátok ezt a HUP-on. Ha nem a C nyerne, akkor pedig vice versa, megígérem, hogy nem fogom a továbbiakban az orrotok alá dörgölni, hogy felültetek a hypenak és bedőltetek a marketing bullshitnek. Ez így fair, nem?

https://gitlab.com/bztsrc/langcontest

A feladat: egy olyan rendszerprogram írása, ami nem csinál mást, mint másodpercenként eggyel növel egy számlálót a képernyőn. Elég egyszerű, nem lehet probléma bármilyen nyelven megírni ezt, igaz?

A verseny szabályait igyekeztem úgy kialakítani, hogy azok a lehető legegyenlőbb feltételeket biztosítsák, bármilyen nyelvről és fordítóról is lett légyen szó, és igazságos összehasonlítási alapot szolgáltassanak:

- architektúrának a 64 bites x86-ot választom, mert arra minden nyelvhez biztos van fordító és könnyedén tesztelhető, ráadásul tele van hozzá doksival a net
- mivel nincs oprendszer, a betöltőt biztosítom, emiatt nem kell aggódni, nektek csak egyetlen lefordított rendszerprogramot kell csinálni
- bármilyen nyelv használható, az Assembly-t leszámítva (a betöltő teszteléséhez egy Assembly-ben írt referencia implementációt biztosítok)
- inline Assembly nem, csak az adott nyelv natív utasításkészlete használható, a forrásnak hordozhatónak kell lennie (azaz hiba nélkül le kell fordulnia többféle architektúrán, akkor is, ha úgysem működne ott)
- nem használható semmi olyan kulcsszó vagy opció, ami kikapcsolja a nyelv alap funkcióit, mert az úgy már nem a csodanyelv lenne (pl Rust-ban az unsafe/unmanaged, vagy C++ alatt az -fno-exceptions/-fno-rtti nem megendegett)
- bármilyen más kulcsszó, parancssori opció használható, akár fordítóspecifikus, architektúraspecifikus is (például hívási, optimalizálási, ellenőrzési, kódgenerálási, linkelési stb., bármi más mehet, csak a nyelv alapkészletét tilos leszűkíteni)
- bármilyen fordító megengedett, ami képes az adott nyelvet lefordítani (például Go esetén gcc-go/golang, C esetén gcc/Clang stb., semmilyen megkötés nincs a fordítóra)
- bármilyen szabványos függvénykönyvtár használható, ami a nyelvvel és a fordító telepítésével együtt érkezik vagy Ti írjátok, de harmadik féltől származó, netről letöltött nem (ha a nyelvnek van bare metal változata, természetesen azt is ér használni)
- bármilyen fordítási segédprogram megengedett, olyan is, amit külön kell telepíteni vagy saját fejlesztésű (például interface bindolók, fejléc generálók, linker szkriptek, binutils, make/mk/cmake/ant/scons/meson/ninja/azanyjakinyja stb.)
- a lefordított program nem lehet nagyobb, mint amit egyetlen BIOS hívással be lehet tölteni a lemezről (65024 bájt)
- a képernyőre VGA teletype módban kell írni (ASCII karakter (0x30 - 0x39) + attribútum (0x07 fehér) párosokból álló tömb a 0xB8000 fizikai címen a Video RAM-ban)
- a pollozás nem megengedett, mert az nem lenne sem hatékony, sem energiatakarékos, sem pontos
- a program megírására 1 hónap áll rendelkezésre
- egy program többször is módosítható és többször is beadható ez idő alatt, a legutolsó fog számítani (lehet reagálni a mások által beadott pályaművekre, és lehet újabb optimalizációkkal előrukkolni)
- a nyertes az a program, ami a legkevesebb segédprogramot, kulcsszót és specifikus opciót használja az adott nyelv készletéből (magyarán ami a legkevésbé gányolt), ezen kívül pedig ami legkissebb bájtméretű, működő binárist produkálja, holtverseny esetén meg ami a kevesebb memóriát fogyasztja futás időben (vermet is beleértve)

A felsorolt limitációk a hardveres futási környezet sajátosságai (long mód, BIOS betöltés, VGA képernyő), ezek nem megkerülhetőek, muszáj alkalmazkodni hozzájuk.
Elvileg a 64 bites long mód nem tartozna ide, de ennélkül már a verseny indulása előtt nyerne a C és elvérezne az összes többi csodanyelv... :P De jófej leszek és esélyt adok nektek, így legyen hát 64 bit only.

A függvénykönyvtárakra vonatkozó megkötés azért került bele, hogy csak a nyelv maga számítson. Standard lib használható, de el is hagyható, 3rd party lib viszont tilos, mert az már nem a nyelv része.

Hogy a fordítási környezetből adódó eltéréseket is kiiktassuk, két betöltőt is biztosítok: az első ELF binárist tölt be, és SysV ABI-t használ:

cat boot_elf.bin programod.elf > disk.img

A másik pedig PE/COFF binárist és MS fastcall ABI-t (pont, mint az UEFI):

cat boot_pe.bin programod.exe > disk.img

Mindkét esetben az elkészült virtuális lemezt qemu alatt, a következő paranccsal kell tudni futtatni:

qemu-system-x86_64 disk.img

Hogy a programokba tényleg ne kelljen Assembly betét, a betöltő a bináris fejlécében megadott linkcímekre másolja a szegmenseket, kinullázza a bss-t, beállítja a vermet lefele növekvően 640K-ra, az alacsonyszintű CPU utasításokhoz pedig interfészt és wrapper függvényeket biztosít, mielőtt a belépési pontot meghívná.
Relokációt nem végez, a programot linkeljétek valaholva a 96K és 640K vagy az 1M és 2M közé, ahová jólesik, és több szegmensből is állhat akár.

Az interfészt pontosan ugyanúgy kell használni, mint UEFI esetén, csak itt más függvényeket tartalmaz. Ennek a C nyelvű definíciója:

typedef struct {
  void (*load_idt)(const void *buffer, const uint16_t size);  /* betölti a megszakításkezelőket */
  void (*enable_interrupts)(void);                            /* engedélyezi a megszakításokat */
  void (*disable_interrupts)(void);                           /* letiltja a megszakításokat */
  void (*iretq)(const int localsize);                         /* visszatér a megszakításkezelőből */
} almost_efi_system_table_but_not_quite_t;

A program belépési pontja egy mutatót kap paraméterül erre a struktúrára, pontosan úgy, mint UEFI-nél.
EDIT: mivel sokan sírtatok, ezért módosítás: az összes paraméternél kiírtam, hogy const, ha ez nem lett volna egyértelmű, és ezeknél a függvényeknél, és szigorúan csakis ezeknél az interfész által biztosított függvényeknél használható Rust alatt az unsafe. VAGY Az interfészt egyáltalán nem kötelező használni, le is implementálhatjátok ezt a négy függvényt Rust-ban, ekkor azonban nem lesz külsős függvényhívás, így ilyenkor tilos az unsafe.

Továbbá, hogy még a hardverprogramozási készségek se számítsanak, és tényleg csak a nyelveket mérjük össze, a betöltő megteszi azt a szívességet is, hogy előre felprogramozza a megszakításvezérlőt valamint a PIT-et másodpercenkénti 100 IRQ megszakításra, azonban nem kezd megszakításokat generálni, míg az enable_interrupts() függvényt meg nem hívjátok.
Hasonlóan az iretq() hívás gondoskodik a megszakításvezérlőben az IRQ nyugtázásáról is, így azzal sem kell törődnötök. A load_idt() híváshoz segítségként, 32 kivételfajta van és 16 IRQ, a kódszelektor a 32-es, a megszakításkapu attribútuma meg a 0x8E.

Itt az alkalom, hogy bizonyítsátok, a Go, Rust vagy bármelyik másik agyonhypeolt csodanyelv valóban képes lehet a C leváltására! Én állítom, hogy nem, bizonyítsátok be, hogy tévedek! Versenyre fel!

Hozzászólások

Ez nem bizonyítás. A te környezeted egy speciális eset.

Semmi olyan feltétel nem szerepel, amit egy rendszerprogramozási nyelvnek gondot jelethetne. Semmi.
Sőt, még kifejezetten könnyítettem is a feltételeken, normál esetben nektek kéne felprogramozni a PIT-et és a megszakításvezérlőt, de itt ezt megteszi helyettetek a betöltő.

Arra gondolok, hogy a C jogosultsága bizonyos helyeken nem kérdés (lásd akár a saját példád), bizonyos helyeken pedig ma már ésszerűbb egy magasabb szintű programozási nyelvet használni. Emiatt a te példàd nem bizonyítja azt, hogy hülyeség lecserélni a C-t. Ekkor nem beszéltem az üzleti érdekröl és gazdaságosságról sem, mely szerint egy modernebb magasabb szintű nyelvhez van munkavállaló is.

Arra gondolok, hogy a C jogosultsága bizonyos helyeken nem kérdés (lásd akár a saját példád)

Én meg arra gondolok, hogy a magyar nyelvű szövegértés meghaladja az értelmi képességeidet, mégse hangoztatom ezen véleményem.

Emiatt a te példàd nem bizonyítja azt, hogy hülyeség lecserélni a C-t.

Nyilván, mivel a példámban (egy számláló növelése és kiírása a képernyőre) az égadta világon semmi C specifikus sincs. Sosenemis volt cél!

Mégegyszer, a célja a versenyek az, hogy bebizonyítsátok, nemcsak a szátok jár. Eddig csúfosan felsültetek, mert még egyetlen megoldás sem érkezett. De még van idő bizonyítani.

En csak a popcorn miatt jottem, de a zsurizes szempontjait nem ertem. Attol fugg, hogy levalthato-e a C, hogy hany kulonbozo kulcsszot hasznaltal a kodban? Miert relevans az?

Dehogy kuldok, egy sort nem irtam meg Rustban. Barmi, amit bekuldok, az sokkal inkabb az en Rust-szuzessegemre refeklektalna, mint a C-hez kepest nyujtott lehetosegeire a nyelvnek.

Ettol meg erdekelhet, hogy milyen szempontok alapjan lehet barmirol kategorikusan kijelenteni, hogy "jobb", vagy "rosszabb" a masiknal. Mondott egyaltalan barki olyat, hogy a Rusttol kisebb lesz a binaris merete?

Hát, valamilyen egzakt módon mérhető metrikát csak fel kell állítani. Te mit javasolnál helyette?
(A bináris méretét nézni egyébként egyáltalán nem ördögtől való, ha van két program, ami pontosan ugyanazt csinálja, de az egyik 2 kilobájt, a másik meg 400 Megabájt, akkor nem kérdés, melyik a jobb a megoldás.)

>Te mit javasolnál helyette?

Például, hogy a szerző bizonyítsa be matematikai precizitással, hogy ha a fordító és a runtime a nyelv specifikáció szerinti szemantikáját maradéktalanul betartja, akkor a programja biztosan nem címez félre és nem leakel :-P

Erre egyébként nem válaszoltál, hogy mitől változott meg a b értéke észrevétlenül, mikor nem volt átadva paraméterként, és be volt kapcsolva az address sanitizer is: https://hup.hu/comment/3035799#comment-3035799

Például, hogy a szerző bizonyítsa be matematikai precizitással, hogy ha a fordító és a runtime a nyelv specifikáció szerinti szemantikáját maradéktalanul betartja, akkor a programja biztosan nem címez félre és nem leakel

Rendben, hol van ez a matematikai bizonyítás a Rust esetén? Várom a dolgozatodat!

Ha a 400MB-os is ellatja a feladatat akkor felolem az is jo. Nem, nem jobb a 2Kb-os csakis akkor ha kvarcorara akarom rarakni. De ha egy Spark clueteren akarom elinditani es masfel percig indul a 400MB-os progi, de aztan stabilan fut, konnyebb supportalni es odaadni egy juniornak es tobb feature-el randelkezik mint a 2KB-os akkor az a jobb.

Ennyi.

Nem erdekel kinek nagyobb a fasza. :D

Hát, azért nagyon nem mindegy, hogy egy egyszerű program 0,002 vagy 400 MB, az azért 200 ezerszeres különbség. Még a mai hardveren sem. Az a baj, hogy mindenki így gondolkodik már, hogy legyen minden 400 megás, Electron alapú fos, az is lehetőleg valami konténerizált csomagformátumban, ami betölti a saját libjeit még külön, és csodálkozunk, hogy az isten RAM-ja se elég.

A 400 megás progival meg nem csak az erőforrás-használata a baj, hanem, hogy a fejlesztőnek is több időbe telik minden egyes fordítás és debugolás, ami egy 2KB-os programnál megint kb. arányos különbség. Valószínű a függősége is több a 400 megásnak, meg nagyobb eséllyel törik el egy frissítéskor is.

Azt se feledd el, hogy nem kell feltétlen kvarcóra, mai napig vannak beágyazott eszközökön, SBC-ken, ipari vezérlőkön futó kódok, és ezek a hardverek kb. 486-os szintűek néha. Teljesen valós felhasználási igény, hogy egyes kódoknak ezeken is futnia kell.

A versenyen lehet részt veszek, de még nem ígérem biztosra. Egy C kódot nem nehéz szerintem rá megírni, de annyira egyszerű feladatnak tűnik, majdnem Hello World szintje. Tudom a kiírás tiltja, de poénból megérné ASM-ben írni, sose írtam még 64 bites x86 ASM kódot.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Egyetertek veled. Ha beagyazott eszkozre kell akkor igenis szamit a meret. De egy streaming app eseten ami egy tobb szaz node-os spark clusteren fut ahol a node-oknak egyenkent van 300+ GB memoriajuk inkabb azt nezem, hogy az app elvegzi e a feladatait ugy ahogy az kell neki, magabiztosan es biztonsagosan es minden feature-el amivel rendelkeznie kell. Es nem nem erdekel mekkora a meret (amugy nem lesz 400MB :D)

Az a baj, hogy nem igaz hogy "mindneki ugy gondolkodik". Amit irtal hogy electron meg mifaszom (ahogy latom a Go-t is elohoztad) az korulbelul desktop felhasznalas es azt le se szarom. :D

Az a baj, hogy hiaba mondom nem erti meg a tema nyitoja, hogy nem szukseges semmit sem bebizonyitania. Mert nincs mit. Ezert is kerdeztem hogy kinek akar es mit bizonyitani. Mi foglalkozunk IoT-val is, biztosithatlak hogy ott nem scalaban van megirva az app, ami fut a kis szenzoron.

Azt hogy mi miben van megirva a cel hatarozza meg, de neha meg az sem hanem az uzlet. A valo eletben persze. Mert hobbi porjektet mindenki abban ir amit akar. :D

De vegye csak szó szerint. A számokat nem hasraütésszerűen írtam, hanem életből vett példa. Ablakos alkalmazás, ami egy lemezképet kiír egy meghajtóra: Balena Etcher, többszáz MEGAbájtos electron alkalmazás, versus USBImager, ami párszáz KILObájtos egyetlen függőség nélküli portable executable. Mindkettő nyílt forráskódú, ingyenes, azonos felhasználási feltételekkel bír és mindkettő képes tömörített lemezképet is kiírni.

A bináris méretét nézni egyébként egyáltalán nem ördögtől való, ha van két program, ami pontosan ugyanazt csinálja, de az egyik 2 kilobájt, a másik meg 400 Megabájt, akkor nem kérdés, melyik a jobb a megoldás

Attól függ: ha a homeserveremre kell, hogy lássam, mikor megy a következő metró, akkor az ára + licenc pl nekem sokkal nagyobb tényező, mint hogy mi a mérete - úgyis fillérek már bármilyen hardver. Ha munkakörnyezetbe kell, akkor valszeg a projekt / megrendelő által elvárt követelmények (adott hardver, SLA, ár) lesznek a fő szempontok, és hogy, hogy melyik mennyire teljesíti azt.

Generikusan ki jelenteni, hogy az egyik jobb, mert kisebb, hát... 

Na, mégegy kötözködő, aki csak pofázik, de megoldást, azt bezzeg nem küld.

akkor az ára + licenc pl nekem sokkal nagyobb tényező

Ha nem lett volna nyilvánvaló a leírásomból, a két megoldás MINDENBEN azonos (ár, licensz, SLA stb.), csakis a méretük különbözik, semmi más.

Na, mégegy kötözködő, aki csak pofázik, de megoldást, azt bezzeg nem küld.

Azt hittem, ennek tízévesen vége, hogy a melyik a legjobb konzol jellegű vitákra verjük ki.

MINDENBEN azonos

Ha mindenben azonos, akkor nyilván méretben is. Ha a méretben eltérnek, akkor nyilván másban is el fognak - hogy csak a legtriviálisabb kettőt említsem, az eddig ráfordított erőforrásban, meg az esetleges változtatások által igényelt ráfordítás mértékében. 

versenyezhetneked van

Nincs versenyezhetnékem. Lehetőséget adtam nektek, hogy a gyakorlatban is bizonyítsátok, nemcsak a szátok jár.

nem mindenki ugyanazzal az ertekrenddel nezi a vilagot, mint te

Hát az már biztos! A legtöbb faszkalap úgy mondana a helyemben ítéletet, hogy nem adna lehetőséget a másik félnek bizonyítani. Én valóban nem ilyen vagyok, én biztosítom a lehetőséget Nektek. Kár, hogy eddig még képtelenek voltatok élni vele, de még van idő beadni legalább egy megoldást.

Hát az már biztos! A legtöbb faszkalap úgy mondana a helyemben ítéletet, hogy nem adna lehetőséget a másik félnek bizonyítani. Én valóban nem ilyen vagyok, én biztosítom a lehetőséget Nektek. Kár, hogy eddig még képtelenek voltatok élni vele, de még van idő beadni legalább egy megoldást.

Tippem szerint ennek a fő oka az, hogy jól látszik, hogy Frankói magasságban van a magabiztosságod, és a bármi minimális más vélemény/szemszög befogadásának képessége, ami miatt borítékolható, hogy ebből érdemi álláspont változás nem lesz senkinek se, hiába csinálná meg valaki. Cserébe gyakorlatilag nem tudsz lekicsinylő személyeskés nélkül megszólalni, ezért senkinek nincs kedve veked játszani. 

Semmivel. Egyrészt alátamasztják a te kommentjeid bőségesen, másrészt a suli udvarán se szokták elmagyarázni a toxikus, folyamatosan bunkó kiskampónak, hogy mi a baj, egyszerűen egyre többen, egyre nagyobb ívben kerülik ki, ahogy egyre hangosabban mondja, hogy mind hülyék vagytok, és nem igazán érdekel senkit, hogy elhiszi amit mondd, meg önigazolja magának, hogy igaz, mert nem vesznek részt az izéjében. 

Megoldani meg nem akarom, sose foglalkoztam ilyen alacsony szintű sajtreszeléssel, csk ha muszáj volt, nem mozgat, meg nem is akartam sose kicserélni a kedvenc nyelvedet. Értelmes beszélgetést viszont szívesen olvastam volna, mert láthatóan te se vagy járatlan ezekben, és vannak még egy páran itt, akiknek szintén érdekes meglátásai szoktak lenni. Sajnálatos, hogy a kommunikációs deficited ezt ellehetetleníti. 

Szerkesztve: 2024. 03. 08., p – 17:05

Szerintem te félreérted, hogy hol lehet célszerű Rust-ot használni C helyett. Nem a kódsoroknak abban a 0.01%-ában, ami pl. a kernelek leghardverközelibb része. Hanem a többi 99.99%-ában.

Nem kerülte el a figyelmem. Pontosan ezért lett kiírva ez a verseny úgy ahogy, az összes általad 0.01%-ba sorolt hardverközeli dolgot megoldja helyetted a betöltő, Neked csak a maradék 99.99%-át kell hozzáadnod.
Nem véletlen, hogy a betöltő minden alacsonyszintű CPU utasításhoz biztosít egy wrapper függvényt, amit szabványosan meghívhatsz, mint bármelyik másik függvényt.

A videómemória közvetlen írását hová sorolod? Az egy eléggé hardverközeli dolog.

Továbbra sem akarod megérteni, hogy a Rust a helyességi ellenőrzéseivel pont hogy nem az ilyen feladatok miatt lett bevezetve. Az ilyen dolgokra maradnak az eddigi módszerek, pl. a C, vagy Rust unsafe.

Hat a 99.99%-ot a parent parentjeben egy atlagos szakujsagiro 100%-ra kerekiti - innen indul a feszultseg.

Erdemi valasz:

Amugy inkabb 98%-2%, vagy 95%-5% lesz az szerintem.

Pl. openssl forkot irnal Rustban? Hasznalnad a C-s openssl/libressl/boringssl helyett?

Irtam en mar python + bash komboban drivert, mert csak arra volt ido. Jol performalo nem volt, de mivel percenkent 8 packetet se kellett kikuldeni a soros porton, "senki nem vette eszre".

Azert hozok peldanak SSL-t, azt van, hogy masodpercenkent sokszor szamolja a rendszer, megsem hardverkozeli.

Pl. openssl forkot irnal Rustban?

Van ilyen: Rustls

 Hasznalnad a C-s openssl/libressl/boringssl helyett?

Vannak akik használják production-ben, még olyanok is vannak, akik ezt ajánlják openssl helyett. ;-)

Azert hozok peldanak SSL-t, azt van, hogy masodpercenkent sokszor szamolja a rendszer, megsem hardverkozeli.

A fenti reddit fórumban épp azt írják, hogy sokkal gyorsabb a Rustls, mint az Openssl.

nem talaltam meg, hogy gyorsabb, sem azt, hogy az hogy lett merve.

Csak írták, hogy gyorsabb, mérés nem volt mellette. Pl.:

Performance depends on use-case, but generally rustls is faster.

Rustls is a promising project that seems to have quite a performance boost on OpenSSL, is refusing to implement some dangerous legacy behavior and might be automatically impervious to many problems OpenSSL has had.

Pl. openssl forkot irnal Rustban? Hasznalnad a C-s openssl/libressl/boringssl helyett?

Én pl simán lehet, hogy igen, az openssl tipikusan olyan, amiben -- és ezt a vele sokat dolgozó kollégák mondják -- a crypto jó, a kód egyébként programozó szemmel finoman szólva nem az igazi, látszik, hogy kriptósok írják, tehát látnék benne hozzáadott értéket, ha az eszköz, amiben fejlesztenek a memoria kezelési hibák esélyét jelentősen csökkentené.

OTOH ebből a szempontból azért nem annyira rossz az openssl track recordja egyébként.

Szerkesztve: 2024. 03. 08., p – 17:19

En meg szeretnem ha olyan programot irna valaki barmilyen nyelven, ami egy kafka streambol kiveszi a JSON uzeneteket, majd bizonyos mezok alapjan a megfelelo DB-be kuldi, ami lehet PostgreSQL, ES, stb. A program stateless legyen, de egy cachebe rogzitse a szamlalokat, valamint kepes legyen logolni JSON-ben mint formatumban es kezeljen sink-eket mint tavoli syslog, ES, Clickhouse endpointokat. Legyen neki egy monitoring API-ja es egy prometheus endpointja is (/metric), ami a cache-ben tarolt szamlalokat adja vissza.

Az alkalmazasnak kepesnek kell lennie bufferelni az adatokat, ha a storage endpoint nem erheto el, vagy reprocessalnia oket a kafka topikokbol.

Aki akarja irja meg C-ben, de mehet felolem Rust-ban is. :D

Ugye, ugye...akkor mitol lenne a C a legjobb nyelv? Attol, hogy megtalaljuk azt a teruletet, amiben a legjobb, masra meg nem azt hasznaljuk ha nem az a legjobb.

A Te feladatod "versenyeztetni" a C-t egy olyan esetben, amire de tenyleg a C a legjobb. 

Azt nem ertem, hogy mit akarsz elerni vele? Kinek akarod bizonyitani, de meg inkabb hogy mit is? :D

akkor mitol lenne a C a legjobb nyelv?

TROLL. Ezt senki sem állította, a verseny célja az, hogy bebizonyítsátok, a csodanyelveitek egyáltalán képesek-e azt a funkcionalitást biztosítani, amit a C kisujjból kiráz.

Eddig csak nyafogást, kifogásokat és trollkodást sikerült produkálnotok, bárminemű bizonyítást kevésbé. (És egyébként pont ezt is vártam, nyilvánvalóan csak széjkaratéban vagytok erősek, de a programozáshoz nem is értetek, pont ahogy sejtettem.)

Az egesz thread egy trollkodas, nem ertem, hogy mit vartal.

Valamilyen random hupu altal bekuldott kodok alapjan te majd eldontod, hogy "továbbiakban nem hangoztathatjátok ezt"? Miert, te ki vagy, mar ne is haragudj? En peldaul innentol minden C-s threadbe bele fogom kommentelni, hogy Rustban sokkal faszabb lenne megcsinalni ugyanezt. Csakazertis. :P

Ember, eletemben nem programoztam komolyan. Mi a faszt akarnek Neked bebizonyitani. Respect azert amiket irtal, a rendszerbetoltoidnel is leirtam hogy ez igen bazdmeg kemeny pocsu legeny vagy. So fuckin' what?

Dolj hatra es nyugodj meg, mert igazad van. Kurvara nem ertek a programozashoz. So fuckin' what?

Ugyanakkor tovabbra is az a kerdes, hogy mi a faszt akarsz bizonyitani es kinek? 

Azt kerdezed, hogy egy nylev kepes e egy szamlalot novelni? Mert ez igy egy altalanos tema amiben ossze lehet hasonlitank azt hogy egyes nyelvekben milyen implementaciokat lehetne megirni. Aztan elkezded szukiteni a lehetseges eseteket es azt mondod, hogy rendszerbetolteskor? Ezzel azonnal kixarva egy csomo nyelvet. 

Szoval akkor csinalok egy versenyt, hogy ki tudja nalam jobban megfozni a kedvenc brassoimat az en szajam ize szerint. Mar tudom is hogy ki nyerne. :D

Na akkor mégegyszer, ez a versenykiírás azoknak szól, akik folyamatosan tépik a szájukat itt a HUP-on, hogy a Rust-nak, Go-nak meg a többi csodanyelvnek le kéne váltania a C-t.
Ez a verseny nekik szól, hogy bizonyíthassák, ez egyáltalán lehetséges-e. Egyelőre még egyetlen egy működő PoC-uk sincs.

na azok is pont olyan evangelistak, mint Te.

Let the religious war begin!!! :D

hobbiprojekteken azt csinaltok amit akartok. Allhat a pocok a C-re, Rust-ra Go-ra, Scala-ra, Python-ra

Az uzlet meg majd eldonti, hogy melyik kell eppen az adott problemara mennyiert mennyi ido alatt es meddig. :D

Az uzlet meg majd eldonti, hogy melyik kell eppen az adott problemara mennyiert mennyi ido alatt es meddig. :D

Kivéve, ha az a pöcök alkalmatlan a feladat megoldására. Akkor mondhat az üzlet akármit, nem fog menni, csak csőd lesz belőle.

Továbbra is várom a megoldásaidat, mert küldeni még egyet sem küldtél. Írhatod Rust-ban, Go-ban, sőt, még akár Python-ban is! Szeretném látni!

Az a baj, hogy amit eddig irtal azt sejteti, hogy fogalmad sincs az uzletrol. Mindenben meg lehet irni mindent. es meg csak az sem biztos hogy a legalkalmasabb eszkozben kell. Sot az sem biztos hogy e legjobb minosegben kell megirni. Sok mindentol fugg. Sot a scope novekedesevel vagy valtozasaval valtozhat az is, hogy mi volt addig a megfelelo es miert. 

De tenyleg nem varom el hogy megertsd mert latom, hogy olyan messze allsz az uzleti elettol, mint en a C programozastol :)

Bocs, de nem értem meg, miért akarod előre megtrollkodni ezt a versenykiírást.

A kiíró előre leírta, hogy rendszerprogram, leírta a feltételeket, leírta a pontozás részleteit. Azt mondhatod, hogy pl Rust unsafe az kellene, és később módosított is a kiíráson.

Nyilván neki is van prekoncepciója, neked is. De míg ő szeretne empirikus bizonyítékot, te azt mondod: hidd el, hogy …., és amúgy is lejt a pálya stb… Mivan akkor ha egy Rust mágus odabasz valami tuti programot, és a kiíró is belátja, hogy tényleg ez a Rust program csak 20%-kal szarabb de eléggé ígéretes stb… Vélhetően a C lesz a nyerő, de engem érdekelne, hogy a többi nyelv úgynevezett hatékonyságban hogyan áll az ilyen feladatok esetén ( én is C kalapáccsal verek be minden szöget, ki is röhög a fiam érte )…., mert hat erre jó a fórum, vagy mi a faszom?!

Mert ez a verszeny: "legem lett a sok nagyszájúból, ezért úgy döntöttem, lehetőséget adok nektek a gyakorlatban is bizonyítani... hogy valójában a gyakorlatban egyik csodanyelv sem képes leváltani a C-t" 

Aztan utana megalkotta azt a kiirast amiben nagyon nagy valoszinuseggel a C fog kijonni gyoztesen. :D

Ez ugyanaz, mintha azt mondom (az o stilusaban): "na sok kis faszkalap, akik semmihez sem ertetek (mert o ert  C-hez es mindan mas csak demagog faszsag, tehat ami azon kivul van az szar), csinaljatok egy jo kajat, de legyen benne csirkemell, liszt, tojas, zsemlemorzsa. En megcsinalom a rantotthust, ti meg probaljatok barassoit, lassagne-t csinalni belole, lassuk meg melyik kis csokottnek sikerul az ami nekem"

Most a tobbi hulyeseget az uzleti eletrol meg minden masrol hagyjuk is. :D

Ok értelek. Csak azt fontold meg pls:

Scenario 1) ( jelen helyzet ): A kiírást ekézitek, 100 hozzászólás arról szól, hogy mekkora idiótaság az egész, és amúgy sem ér semmit az eredmény. Eleve evvel lehúzzátok az egész szakmaiságát, a pályázók által letett eredményt, mert mínuszról indul az egész. Mindenki vérmérséklete szerint basztatja a másikat. A faszméregetés nem vezet eredményre.

Scenario 2): Kiírásra szakmai javaslat: pl Rust unsafe használata. Pályázatok beérkeznek. Mindenki boldog. Szakmai vita elindul, hogy ez ezt csinálja, ez azt stb…, mi miért jó és hatékony, és mi az előnye ennek/annak. Esetleg más szempontok is bejöhetnek stb… Esetleg megismerhetjük pár dologról a bzt szakmai véleményét ( mert az van neki ), esetleg belátna ő is valamit, amit majd egy sör mellett megköszönne ha öreg lesz stb….

A legjobb ügyek is ott akadnak el, hogy az emberek úgy érzik, hogy mindenképpen először a farkukat kell összemérni, pedig evolúciós szempotnból az együttműködés célravezetőbb. Aztán utána már lehet hozni a centit, ha már van produktum.

Senki az eg egegyadta vilagon nem kerdojelezte meg bzt szakmai tudasat. Sot meg en is iszonyatosan tisztelem, amit el is olvashatsz a masik topicokban.

Tiszteletteljesen felhivtak a figyelmet itt egy par dolgora:

1. Senki sem mondta hogy akarmi is levaltja a C-t. Azt maximum, hogy vannak teruletek ahol celszerubb mast hasznalni es nem biztos hogy technologiai okok miatt, hanem uzleti okok miatt

2. A fenhejazo, onmagat piedesztalra emelo, masokat csuklobol lenezo stilus nem fog segiteni abban, hogy ez szakmai forum maradjon

Az a baj, hogy a hatalmas egoja mellett meg sertodekeny is. Es sajnos a sertodekenyseg szemuvegen keresztul egyszeruen nem volt hajlando megerteni mit akarunk mondani. Ha a kiirasbol kivette volna a sertodekenyseget semmi baj nem lenne. Olvasd el a kiirast az elso par mondat nelkul meg azokkal egyutt.

De hogy szakmai is legyek (amitrol mar itt is irtam parszor), korulbelul 2005 tajeken hagytam abba azt, hogy mindenfele teszteket olvassak nyelvek es forditok osszehasonlitasarol teljesitemeny, meg minden ilyen szempont alapjan. Addigra megertettem (es korulbelul felnottem) hogy nem veletlenul csinalnak ujabb es ujabb nyelveket. Nincs egy gyuru, szent gral, tuggyamifaszom. Szoval igen, szerintem meg a sertodott hozzaallas nelkul sincs semmi ertelme a feladatnak. Es hat engedtessek meg nekem, hogy mivel ez egy forum leirjam a velemenyemet. Es ez nem basztatas hanem egy velemeny. Amit nem kell elfogadni, de civilizalt emberek azert meg szoktak hallgatni a masik velemenyet es kultoraltan ignoraljak. Ha nem tudjak elfogadni es elkezdenek tombolni, akkor keszuljenek fel, hogy korejuk kepzelik a gumiszobat es a hatul kotos kis kabatkat. :D

Ha az ego erős és hatalmas lenne, akkor nem lenne sértődés, de itt az énkép korántsem stabil, emiatt a sértődés. Attól ne essünk hasra, ha valaki 20++ év után ért a saját területéhez. A baj az, hogy neki ez mérőszerszáma lett, így szerinte aki ehhez nem ért az hülye.

Egyetertek.

Idezek a nyitobol:

Ha nem a C nyerne, akkor pedig vice versa, megígérem, hogy nem fogom a továbbiakban az orrotok alá dörgölni, hogy felültetek a hypenak és bedőltetek a marketing bullshitnek.

Ezert van teljesen igazad.

Nem az eltolt golvonalra kell panaszkodni, hanem bullshit helyett koddal bizonyitani. Kinos, hogy milyen sok embernek megy a szovegeles, de kodot irni mar szinte mindenkinek derogal.

Egyebkent nekem golgota ellenkihivasa is tetszik: tud-e valaki C/C++-ban optimalis adatszerkezetet irni, ami beszel jsonnal es ES-csel.

Kulon pikans lenne, ha valaki felhasznalna a megoldasahoz pl. a PostgreSQL forraskodjat. :D

Iszonyat egyszeru lenne szerintem C-ben is megirni, mivel az egesz csak protokol es szerializacio. Mas kerdes hogy akar pythonban 3 sor es kb. fel ora annak aki most ismerkedik a python nyelvvel. Hogy atom stabil lesz a az a 3 sor python (jo kicsivel tobb, de erted mit akarok mondani)?. Ki tudja. Ha mikroszervizkent inditom akkor leszarom mennyire stabil, majd ha ujraindul akkor folytatja amit elkezdett. Na igen, de akkor mar kell egy cache, amiben rogziti mi az utolso adat amit kiszedett a kafka topic-bol, szoval johet a cache-el valo beszeles implementazioja is, na az megknt par sor a kezdo python progamozonak. De egy ugyes kezu scala-s megirja ugyanannyi ido alatt, mint egy pythonos kezdo.

Hogy meyik a jobb, fasz se tudja, majd a business eldonti. De hogy nem C-ben kell megirni az tuti. Meg lehet? Meg hat. Erdemes? Egy nagy budos lofaszt. :D 

A postgresql forraskodja mondjuk nem tudom hogy kerul ide ehhez a kerdeshez, mert semmi koze az ES-hez vagy a Kafka-hoz, bar mondjuk tud JSON-t tarolni (JSONB adattipus), de itt siman azt kell tudni a proginak, hogy egy JSON-t rakuld egy HTTPS kapcsolatra adott API-ra. Ezt meg meg nodejs-ben is baszott konnyu megirni. De gondolom C-ben is van "request" meg JSON library.

A masik oldal a nehezebb, amikor a Kafla-bol kiolvasod a nyers adatot es egy yaml leiro szerint aggregalod a memoriaban, de elosztott modon (ala SPARK), mert mi van ha egy 4 kb-os adatbol kell kivenni, de mi van ha mondjuk egy 3GB-osbol, es ebbol is az utolso 5 perc osszes envelopjaban levo adatbol kell legyartani az aggregaciot. 

Na mindegy is. Itt hidd el nem a C a nyero meg ha meg is lehet irni benne.

>Senki az eg egegyadta vilagon nem kerdojelezte meg bzt szakmai tudasat.

De, én megkérdőjeleztem. A memóriakorrupció elleni védelmet nem érti hogy hogy működik se C-ben, se a menedzselt nyelvekben, hiszen egyenlőségjelet tesz a Valgrind és tsai illetve a garantáltan biztonságos memória menedzsment közé. C-ben azt állította, hogy mindent ki tud fogni a Valgrind, pedig sajnos nem. A Rust memóriákezelésre pedig azt állította, hogy ugyanazt generálja, mint a C ASAN, pedig nagyon nem. Ez olyan mértékű tévedés, ami mellett nem lehet csak úgy elmenni, kapott linkeket és példákat is, mégis köti az ebet a karóhoz. Ettől még tudhat rendszerbetöltőt írni, csak nem ismeri az eszközeit senior szinten. Nem baj, lehet produktívnak lenni az ő szintjén is, csak nem kellene arcoskodni olyan területen, amit nem ismer.

Még arra is vettem a fáradságot, hogy csináljak neki egy példát, ami demonstrálja a mondandómat, csak "elfelejtett" válaszolni rá: https://hup.hu/comment/3035799#comment-3035799 Majd pont még rendszerprogramot is fogok írni neki Rustban.

egyenlőségjelet tesz a Valgrind és tsai illetve a garantáltan biztonságos memória menedzsment közé.
 

Szerintem elbeszéltek egymás mellett. Mind a ketten igazat írtok. A C többek között a memória területen történő egyszerű matatásra felkészített nyelv, ez magában hordozza a problémák jellegét: nevezetesen nem lehet egyértelműen eldönteni a “hibák” egy részénél, hogy szándékos-e egy adott terület írása vagy sem. Kidolgozni ellenőrző mechanizmust csak azokra az esetekre lehet, amelyek egyértelműen eldönthetők: Pl free hiánya, buffer overflow, és ezekre ellenőrző mintázat írható.

Az általad irt példa halmozott probléma, talán erre is lesz majd pattern vagy a fordítóban vagy egyéb segéd programban mint pl Valgrind.

>Mind a ketten igazat írtok.

Kivéve, hogy bzt téved. Konkrétan azt írta, hogy a Rust is ugyanolyan kódot generál, mint az ASAN, ami blődség, és pont a lényeg megértésének hiányára utal. Én is követtem már el szakmai tévedést, és még ragaszkodtam is hozzá egy darabig, de aztán a végén csak utánajártam és korrigáltam amit még lehetett. De ez már túlzás, hogy megír egy komplett számláló rendszerprogramot, hogy "bizonyítson" valamit amit senki se ért, de közben nem néz végig egy Rust vagy Java tutoriált, hogy mégis hogyan működik a memória biztonság.

>Az általad irt példa halmozott probléma, talán erre is lesz majd pattern vagy a fordítóban vagy egyéb segéd programban mint pl Valgrind.

Nem értem mitől lenne halmozott, egy darab elrontott pointer aritmetika van benne. A minta egyébként simán előfordul C programokban, hogy pointer szerint matatunk valamit.

Az első esetben annyit kellett trükközni, hogy két külön forrásban legyen az sprintf és a buffer, így a compilernek sosincs meg az egész kontextus, ezért nem tud fordítási időben bufferméretet ellenőrizni. Nem hajánál fogva előhúzott minta, számtalanszor láttam ilyet valódi programban is.

A másodikban azért van pointer szerinti kiíratás, hogy garantált legyen, hogy a b változót is stackre allokálja a fordító. Ha mindkettő stacken van, akkor máris elérhető egyik a másik hibás offsetelésével. A kérdés csak az, hogy mennyi az offset, ami fordítófüggő, de mindig van olyan szám, amivel éppen észrevétlenül hibázik a rendszer.

A menedzselt nyelvekben azért nem lehet ilyet csinálni, mert "pointer helyett" "referencia" van, ami pointer+méret+típus információ és minden esetben ellenőrzive van, hogy pontosan oda címzünk amire jogunk van. Az ellenőrzés sokszor lehet fordítás idejű zéró plusz költséggel (egyébként érdekes módon pont azon egyszerű esetekben tud fordítási időben ellenőrzni a fordító, amikor a C fordító is tud érvelni a pointer méretére), de amikor plusz utasítás, akkor se óriási a költség, mivel regiszterben vagy cache-elt memóriában közlekedik a metaadat, amit gyorsan el lehet érni.

garantáltan biztonságos memória menedzsment

Jaj, hagyjál már! Ilyen vagy nincs, vagy ha létezik, az egyúttal azt jelenti, hogy nem tudsz megcsinálni benne bármit, amelyre a hardware képes. Azt nem nevezném fejlődésnek, hogy elvész a lehetőség, korlátolt lesz a működés. Nekem az a jó nyelv, amelyben bármit le tudok írni, amit egyáltalán el tudok képzelni. Az assembly ilyen, tehát az egy jó nyelv. A C is nagyjából ilyen, az is egy jó nyelv. Bár ott már lehet, hogy bajlódni kell a linker scripttel, ha például bootloadert írsz, vagy a main() előtt kell valamit futtatni, akkor el kell olvasni, az adott fordító hogyan ad lehetőséget egy kis assembly kód futtatására. A többi az korlátolt.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ez egy trade-off. Minél több megszorítást csinálsz, annál kevésbé lehet hibákat elkövetni (ne menjünk messzire, MisraC). Cserébe elveszik a kezedből a "kreatívkodást". Ami lehet jó, de ha a kipörgésgátló szoftvert fejleszted a kocsimba, vagy a lélegeztetőgépet amit életben tart, akkor nagyon nem mindegy, hogy mennyire lehet kreatív a fejlesztő, vagy mennyire tud bizonyíthatóan hiba nélküli kódot írni. Ennek nyilván sok szintje van, és nem véletlen hogy sok helyen a kódot modellből generálják (aminél pedig bizonyítják a korrektséget).

Értem, amit beszélsz, csak nem tudok vele azonosulni. Ne vegyék el a művész szabadságát! Modellből generálásról jut eszembe, épp MCC van nyitva a hozzászólásom alatt, legeneráltattam C kódot initelésre összekattintgatós módon, erre ez a gyökér UART-hoz generált valami bloat ámokfutást, amelyet perceken belül úgy penderítek ki a kódból, hogy lába nem éri a földet, mert felbosszantott. Ja, nem mellesleg ráadásul elsőre, manuális kozmetikázás nélkül le sem fordult, amit generált. Arra mindenesetre jó, hogy a rengeteg hardware-t vezérlő regiszter initjét összefércelje, mert ennél azért nem bízom benne jobban.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem ismerem a rust-ot, szóval nem mondanék róla véleményt. Nekem a C szintaxisa nagyon bejön, nagyon logikus, számomra érthető, és mindamellett még eléggé szabad, nem korlátolt a nyelv, eddig amit kitaláltam, azt meg tudtam benne csinálni. Például megengedi ugyanannak a memóriaterületnek különböző típusú változóként való felhasználását a union által. Nem tudom, a rust-ban van-e a C unionnak megfelelő konstrukció.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

kár veled vitatkozni, aki nem azt mondja, amit hallani szeretnél, az troll, nyafog, kifogás

- a nyertes az a program, ami a legkevesebb segédprogramot, kulcsszót és specifikus opciót használja az adott nyelv készletéből (magyarán ami a legkevésbé gányolt), ezen kívül pedig ami legkissebb bájtméretű, működő binárist produkálja, holtverseny esetén meg ami a kevesebb memóriát fogyasztja futás időben (vermet is beleértve)

Ez egy valid verseny, de attól, hogy a C győz _ebben_, az továbbra sem jelent mást, mint azt, hogy a C és az ökoszisztémája _ebben_ a legjobb. De ettől még nem fog mindenki a fejéhez csapni, és enterprise alkalmazásokat, az adatelemzéseit, meg még ki tudja mit átportolni C-re, mert az a _jó_.

Számtalan ember gyorsabban megír valamit python-ban, ami kell neki, észre sem veszi, hogy felháborítóan lassan fut (hiszen még mindig nagyon gyors), és számukra sosem lesz a C a legjobb nyelv, mert mire megtanulja, megérti, hogy hogy kéne C-ben ugyanazt megoldania, 6 körrel marad le a feladatával

Azoknak, akik amiatt nyafognak, hogy rendszerprogramot kell írni: ez van, a C már csak egy rendszerprogramozási nyelv, így ha egy másik nyelv le akarná váltani, annak is minimum rendszerprogramozási nyelvnek kell lennie.

A miheztartás végett, mielőtt kiírtam volna a pályázatot, elkészítettem a referencia megoldásokat Assembly-ben (ezt mellékeltem is), C-ben és Ada95-ben. Tehát jól bejáratott rendszerprogramozási nyelveken egész biztosan gond nélkül megoldható a feladat, felesleges kifogásokat keresni. (Sőt, még azt is elárulom, hogy ahhoz, hogy a C forrás leforduljon gcc-vel és Clang-al is egyaránt, kellett egy ifdef, ha PE/COFF-ba fordít.)

Amennyiben olyan eset állna fenn, hogy a betöltő nem tud betölteni egy érvényes lefordított programot, akkor természetesen ASAP javítom a betöltőt. De eddig csont nélkül indítja az Assembly-ből ELF és PE/COFF formátumba fordított, valamint a gcc-ből ELF, illetve Clang-ból ELF és PE/COFF formátumba fordított binárisokat.

A problema hogy ugy akarod eldonteni hogy melyik a jobb nyelv, hogy egy specialis feladatot talaltal ki, amire a C a legjobb. 

A fenti bigdata streaming (spark/flink) vagy stateless microservice aplikaciot is meg lehet irni C-ben is, sot meg lehet gyorsabb is lesz maga a program, de ide a rozsdas bokot, hogy egy ugyes scala programozo 10ed annyi ido alatt rakja ossze.

Sot ismerek olyat, aki C++-ban irt ML/Anomaly detection progit par nap alatt. Szep-szep. De python-ban ugyanazt meg lehet irni fel ora alatt. Es nem, ez nem jelenti azt hogy a python "jobb nyelv" lenne. Azt jelenti, hogy penz beszel, kutyaszar tancol, es uzleti szempontbol kurva mindegy hogy a C a vilag legjobb nyelve e vagy sem. :D

A problema hogy ugy akarod eldonteni hogy melyik a jobb nyelv, hogy egy specialis feladatot talaltal ki, amire a C a legjobb.

Ez konkrétan hazugság. Erre a feladatra az Assembly a legjobb, de nem is ez volt a kérdés, és még mindig nem árultad el, hogy egy számláló növelésében és kiírásában mi lenne a speciális. Csak nyafogsz.

Ha a feladat lényege az, hogy ki tud gyorsabban minnél több middleware-t berántani a kódjába, akkor azzal NEM a nyelv kifejezőerejét teszteled.

A feladat, hogy valami noveljen egy szamlalot. Ha megteszi, akkor jo. Korulbelul mindegy miben irjak. Leszarom, hogy assembly, C, Rust, python, lofasz.

Se a merete, se "gyorsasaga", se a resource ehsege nem erdekel addig, amig valaki ezt nem rakja be a kovetelmenyek koze. Meg csak az ssem, ha valaki a jovo honapban adja azt le neked, mert addig irja mas valaki meg megirja egy perc alatt.

A Te kovetlemneyeid akkor lennenek jok, ha azt mondanad: ferjen bele 2KB-ba, a maximalis cpu hasznalata legyen X ciklus, a memoria hasznalata maximum X byte, stb stb., es most inditod a stoppert, holnap reggel nyolcra legyen a git-ben egy branchen.

A jelenlegi kirasban nekem minden megoldas tok egyforman jo. Minden nyelv szuper :D

Szerkesztve: 2024. 03. 08., p – 17:22
.>+[+++++++++[-]<+>++++++++++<<[->+>-[>+>>]>[+[-<+>]
>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>+
>>]<<<<<]>[-]>>[>++++++[-<++++++++>]<.<<+>+>[-]]<[<[
->-<]++++++[->++++++++<]>.[-]]<<++++++[-<++++++++>]
<.[-]<<[-<+>]>+]

Már csak az időzítésen kell dolgozni.

[insert line here]
B.C. 3500 - DIY Vehicle / A.D. 30 - DIY Religion / A.D. 1991 - DIY OS

>megkaptad a lehetőséget, hogy gyakorlatban is igazold, nemcsak a szád jár.

Konkrétan mit is? Ha visszaolvasnád a hozzászólásokat, a tényszerű tévedést javítottam csak, miszerint a C-re továbbra sem lehetséges maradéktalanul memória túlcímzést ellenőrizni. Ennyi volt az állításom, ezt nem tudod cáfolni, mert így van. Rust evangelista nem vagyok, mert még alig ismerem. Szerintem érdekes téma, de eddig nem volt időm rá: érdekes és pénz hozó projekteken dolgozom, úgyhogy nem panaszkodok, de hiába érdekel, nem Rustoztam eddig egy tutoriálon túl.

Talán a Java a kedvenc programozási nyelvem a libekkel és eszközökkel együtt. De sosem állítottam, hogy rendszerprogramozásra alkalmas volna.

Azt nem veszed észre, hogy az alap állításoddal nem is álltam szembe, szeretem is a C-t, dolgozok is vele. Csak annyira fel vagy fuvalkodva, hogy mindenre vagdalkozol ahelyett, hogy gondolkodnál inkább.

Az szerintem nyilvánvaló, hogy bármilyen menedzselt nyelvhez szükséges az unsafe opciók használata ahhoz, hogy interfészeljünk a hardver környezettel. A kiírást nem gondoltam végig, de sejtem, hogy itt ugyanez van, nem tudsz C-be belehívni unsafe nélkül, mert C-t hívni eleve unsafe a Rust nyelven belül. (Tippre, nem néztem utána és talán nem is fogok.)

A környezethez drótozó kódokon kívül a többi viszont már lehet safe, az a logika, hogy egy timer szerint, vagy a buffer swap interruptból triggerelve beírunk két bájtot az már gyerekjáték. A nehézséget a C API elérése és a timer felrpogramozása jelenti. Mivel C API-t adtál, ezért ez pont olyan mint a Róka és a Daru vendégsége. Én meg kiírok egy versenyt, adok egy Java API-t, és az nyer aki a legegyszerűbben használja a Java API-t. Írhatsz JNI-t rá, de bukod mert túl bonyolult lesz.

A Rustnak nem engedni az unsafe-t, az itt nem fair, mert az olyan mintha én azt mondanám, hogy te meg futtas rendszerbetöltőt Valgrinddel, de úgy, hogy ne mondd meg neki, hogy a rendszer regisztereihez hozzá szabad férni direkt címzéssel. Úgy kivág mint macskát szarni. Ha meg megmondod, hogy ezeket neked szabad, az pont olyan mint Rustban az unsafe.

LOL

Az szerintem nyilvánvaló, hogy bármilyen menedzselt nyelvhez szükséges az unsafe opciók használata ahhoz, hogy interfészeljünk a hardver környezettel.

A feladat direkt úgy lett kiírva, hogy NEM kell hardver környezettel interfészelned, a betöltő szándékosan elfedi ezt előled és egységes, magas szintről hívható funkciókat biztosít.

A kiírást nem gondoltam végig, de sejtem

Rosszul sejted.

Mivel C API-t adtál

Nem. De persze nem várom el a Te szövegértési képességeiddel, hogy felfogd, egyaránt biztosított a SysV ABI és az MS fastcall ABI is, szabadon választhatsz.

Felmerül a kérdés, hogy te egyébként ismered azt, amit fikázol? Konkrétan a Rustról, vagy akár bármilyen menedzselt nyelvről van bármi fogalmad? Hogy amikor arról beszélünk, hogy véd a memória félrecímzéstől, akkor az hogyan működik? Mert ha értenéd, akkor tudnod kellene, hogy nem lehet a nyelvből kihívni unsafe nélkül. A kulcsszót nem tudom, hogyan kell alkalmazni, de nyilvánvaló, hogy a nyelv a garanciáit nem tudja biztosítani akkor, ha belehívsz C-be, tehát unsafe.

De ez nem baj, mert csak beírod, hogy unsafe, a projekt résztvevői elfogadják a kockázatot és minden működik.

De unsafe kulcsszó nélkül elvi okok miatt nem működhet. Vagy annyira nem érted a koncepciót, hogy eleve nem érted, vagy ha érted a koncepciót, akkor nem tisztességes a kiírásod. Döntsd, hogy melyik eset forog fenn, aztán módosítsd úgy a kiírást, hogy lehet használni az unsafe kulcsszót, illetve ha szükséges, akkor egy minimális illesztőt is. És máris lesz talán aki megcsinálja neked.

ha belehívsz C-be

Ennél a feladatnál sehol sem kell "belehívni C-be". És még választhatsz is, hogy milyen ABI-t szeretnél az interfészhez.
Ráadásul a függvények még véletlenül sem nyúlnak a program memóriájához, csak CPU utasításokat ágyaznak körbe, így még annak sem lehet akadálya, hogy immutable-ként definiáld Rust alatt, ha épp úgy szeretnéd.

- a nyertes az a program, ami a legkevesebb segédprogramot, kulcsszót és specifikus opciót használja az adott nyelv készletéből (magyarán ami a legkevésbé gányolt), ezen kívül pedig ami legkissebb bájtméretű, működő binárist produkálja, holtverseny esetén meg ami a kevesebb memóriát fogyasztja futás időben (vermet is beleértve)

Igen, nalunk is minden team pontosan ezen kriteriumok alapjan donti el, hogy mi a legjobb megoldas egy feladatra.

#janem

Igen, mert nálatok a teamek ahelyett hogy dolgoznának és termelnének, azzal vannak elfoglalva, hogy különféle nyelveket hasonlítsanak össze. Paraolimpián nem indulnak a teamjeitek? (szarkazmus)

Ennek a versenynek hogy lehetne már ugyanaz a célja, mint egy cég részlegének? Sehogysem.

Ennek a versenynek hogy lehetne már ugyanaz a célja, mint egy cég részlegének? Sehogysem.

 

No igen, nehez meroszamot rendelni ahhoz, amikor rendben van a doksi, a CI, a re/un/... deploy; van failover, backup es monitoring, vannak processzek, megismetelheto, atveheto a fejleszes es uzemeltetes, van 24/7 pager duty, van biztonsagi audit, es meg sorolhatnam.

Sokan, akik nem dolgoztak meg kozepes/nagy cegeknel, nem is tudnak ezekrol. Nagy cegeknel a jo kod max. a fele a requirement-eknek. Siman van atlagosan minden koder melle egy SRE/Security/PO/IA/BA/PM fo. Egy 3-5 fos team melle siman egy 3-5 fos support garda tartozik, akik a (developer szemszogbol) "kulimunkat" vegzik.

Kis cegnel ezeket altalaban elsumakoljak, vagy annyira egyszeru a landscape, hogy egyvalaki megcsinalja kaveszunetben. De nagy ceg ezt nem engedheti meg maganak; egy esetleges sulyos leallasbol, security breach-bol, adatvesztesbol akkora veszteseget tud 'kitermelni', amibol kijon a teljes IT eves fizuja... Mas a nagysagrend.

Én nem programozok vagy 25 éve, de üzemeltetőként is értem, hogy miért háborodott fel bzt kolléga és mit szeretne megmutatni ezzel a versennyel.

Aki itt (is) vitatkozik, az vagy nem érti (ez fura, le lett írva ezerszer), vagy csak a vitatkozás/ellentmondás kedvéért írogat ezekbe a topikokba (aminek meg semmi értelme igazából jelen esetben).

Az utóbbi napok C/C++ kötődésű topikjainak lényege, hogy azt állították (cikkek, hozzászólók), hogy a C/C++ leváltása felé kezdenek mozdulni még a legnagyobb programgyárak is, mert azok jobbak (főleg a memóriabiztonságra hivatkoznak). Itt a _leváltáson_ volt mindig a hangsúly, nem a jobbságon. Mert ugye az nagyobbat üt a neten, hogy "leváltjuk az 50 éves technológiát", mint az, hogy "bizonyos dolgokat más nyelven írunk mostantól".

Na, ez a verseny arról szól, hogy a C/C++ elég valószínűleg nem leváltható, mert vannak feladatok, amik csak ezzel, vagy ezzel sokkal hatékonyabban oldhatóak meg.

Teljesen nyilvánvaló, hogy manapság egy ügyviteli program megírásához nem C nyelven kezd hozzá senki, mert ugyan tökéletesen alkalmas rá, csak kicsit tovább tartana, mint egy UI-s felhasználói program fejlesztésére kitalált nyelven/rendszerben (pl. C# és a .NET, WPF ökoszisztéma hozzá). De sok kernel rész, meghajtóprogram, idő/teljesítmény kritikus feladat esetén ma is a C-t vagy hozzá hasonló alacsony szintű nyelvet kell elővenni, ha nem is az egész program készül benne.

Én bízom azért benne, hogy lesz, aki megírja valamilyen nyelven, ha más nem, a móka kedvéért!

Én bízom azért benne, hogy lesz, aki megírja valamilyen nyelven, ha más nem, a móka kedvéért!

Szerintem itt a HUP-on nagyon kevesen vannak, akik ilyen alacsony szintű programozással foglalkoznak, ráadásul azt ne C-ben csinálnák már évtizedek óta. Nem gondolnám, hogy közülük van egy is, aki hajlandó lenne ezt Rustban megírni.
Így én nem igazán bízom ebben.

Esetleg akkor lenne holmi esély, ha valaki megírná legalább C-ben, nyilvánossá tenné a kódot.

Ilyenkor már nagyobb eséllyel tudnák a Rust-ot ismerő, de ilyen alacsony szintű programozást nem ismerő, programozók azt átírni.

Sőt, azt mondom, akkor lenne a verseny korrekt, ha a kiindulási C kódot a verseny kiíró nyilvánossá tenné!

Én beágyazott programozó is vagyok, C-ben kiismerem magam, a Rust érdekelne, és kifejezetten jó mókának tűnne ilyesmit írni AMD64-re. De az agresszív kismalacos hozzáállás miatt úgy érzem akármit is hoznék össze, arról kiderülne, hogy eggyel több unsafe kulcsszó van benne, vagy kellett hozzá egy ASM betét, vagy ilyesmi, és ezért érvénytelen az egész.

Nem értem bzt miért idegenít el magától mindenkit, mert kifejezetten érdekesek lehetnének ezek a témák ha nem vagdalkozna hozzá. Olyan mint egy Apple fanboi, aki a C-ért rajong az Apple helyett :-)

Nem tudom x86-on hogy van, de például ARM-eken vagy AVR-eken is kell néhány "compiler intrinsic" vagy assembler betét ahhoz, hogy a rendszer alapjait le tudjuk tenni, amire már lehet szabványos vagy MISRA C-t írni. Ezért a Rust-tal szemben is az volna az ésszerű, hogy a rendszer "szélén", azaz ahol a számára külvilággal interfészel, ott engedjük meg az unsafe használatát. Hívj meg egy ABI-t, ami nyilván eltér a Rust hívási konvenciójától, de ne használj unsafe-t! Teljesen korrekt versenykiírás. Pedig amúgy érdekes lehetne.

Bocs, de ezen a szánalmas kifogáshalmazon akkorát röhögtem, hogy kicsordult a könnyem is tőle :-D

Nem értem bzt miért idegenít el magától mindenkit, mert kifejezetten érdekesek lehetnének ezek a témák ha nem vagdalkozna hozzá.

Én nem vagdalkozom, összekeversz valakivel! Még az idióta hozzászólásaitokra is igyekszem kulturált válaszokat adni, nézd csak végig ezt a topikot! Nem rám gondoltál.

kell néhány "compiler intrinsic" vagy assembler betét ahhoz, hogy a rendszer alapjait le tudjuk tenni,

Na akkor neked is leírom mégegyszer, hogy pont erre van a betöltő és az interfésze, és ezért lett kiírva a verseny úgy ahogy. A megoldáshoz NINCS szükség sem alacsony szintű programozásra, sem Assembly betétekre. Nyilván, különben nem nyelvek összehasolítása lenne.

ahol a számára külvilággal interfészel, ott engedjük meg az unsafe használatát.

De hisz ott meg van engedve... Pedig nem is kellene, de engedtem a sirákozásaitoknak. Ez többé már nem lehet kifogás.

>Pedig nem is kellene

Na, várj! Akkor te ezt már megcsináltad Rust-ban? Tehát _tudod_, hogy nem kell? Tehát nem is úgy írtad ki a "versenyt", hogy ne lehessen Rust-ban megcsinálni? Vagy úgy gondolod hogy egy ideális világban nem kellene? Nem igazán értelek, hogy mivel mit akarsz mondani.

Tehát nem is úgy írtad ki a "versenyt", hogy ne lehessen Rust-ban megcsinálni?

Természetesen nem. Már pusztán az a tény, hogy a kiírás végigolvasása után mégis ezt feltételezted, Téged minősít.
Mint ahogy azt direkt külön le is írtam a kiírásban, úgy lett kialakítva a versenyszabály, hogy azt bármilyen rendszerprogramozási nyelven könnyedén meg lehessen oldani. Akár Rust-ban is.

Vagy úgy gondolod hogy egy ideális világban nem kellene?

Még a Rust dokumentációja is azt állítja, hogy nem kell. Sem egy ideális világban, sem a gyakorlatban nincs rá szükség ehhez a feladathoz. Az interfész egyáltalán nem használ Rust memóriát (!), nem foglal, nem szabadít fel, nem módosít egyetlen változót sem; mindössze az egyik függvénynek kell átadni (kizárólag olvasásra) egy konstans, immutable tömböt. Rust szemszögéből a betöltő által biztosított minden függvény safe.

Nem igazán értelek, hogy mivel mit akarsz mondani.

Hát azt látom.

Még a Rust dokumentációja is azt állítja, hogy nem kell.

Úgy látom nem sikerült elolvasnod azt, amit belinkeltél.

Rust szemszögéből a betöltő által biztosított minden függvény safe.

Rust szemszögéből minden külső függvény unsafe, lényegtelen, hogy szerinted safe-re írtad meg.

Sem egy ideális világban, sem a gyakorlatban nincs rá szükség ehhez a feladathoz. 

Pedig ez is le van írva a linkelt doksiban, hogy a direkt memória írása, de még az olvasása is unsafe. Mintha a feladatban szerepelne direkt memória írás, nem? Ezt viszont nem engeded. Akkor mégis úgy írtad ki, hogy Rustban ne lehessen megcsinálni.

If Rust didn’t let you do unsafe operations, you couldn’t do certain tasks. Rust needs to allow you to do low-level systems programming, such as directly interacting with the operating system or even writing your own operating system. Working with low-level systems programming is one of the goals of the language.

Rust szemszögéből minden külső függvény unsafe, lényegtelen, hogy szerinted safe-re írtad meg.

Nagyon nem lényegtelen. Egy állítólagos rendszerprogramozási nyelv esetében meg főleg nem lényegtelen, hogy képes-e külsős függvényeket hívni kompromisszumok nélkül!

a direkt memória írása, de még az olvasása is unsafe.

LOL! Azt állítod hát, hogy e definíció értelmében nem is létezhet safe Rust! Merthogy amit írtál, az bizony ezt jelentené!

>Én nem vagdalkozom, összekeversz valakivel! Még az idióta hozzászólásaitokra is igyekszem kulturált válaszokat adni, nézd csak végig ezt a topikot!

VS

>A legtöbb faszkalap úgy mondana a helyemben ítéletet, hogy ...

>valójában a szánalmas kis faszaid nem tartanak semmit sem össze az IT világában. Bár egy hozzád hasonló ez sosem fogja megérteni, csak amikor már túl késő lesz.

>az idióta hozzászólásaitokra ...

Szerintem a programozás mellett tánc és illemtanár is lehetnél, mert született tehetség vagy ebben is :-)

A faszkalap szóra ha rákeresel, te használtad először. Vagy egy másik topikból idézted? Pont arra akartam utalni, hogy itt is, meg ebben a topikban is szinte kivétel nélkül te kezdted a személyeskedést és a gyalázkodást is: https://hup.hu/node/184578

A vesszőparipám, hogy a C eszközei nem tudják garantálni a memóriabiztonságot, ezért erre a témára reagáltam. Adtam egy példát, hogy mit nem lehet 100%-ban kifogni statikus ellenőrzéssel. Erre a reakció: "Hahahahaha! Te nem fordítottál sok C programot ugye?" Ez még nem túl durva, de akkor is a személy felesleges támadása, ami nem szül jó hangulatot.

Erre _reakcióként_ egyáltalán nem durvábban reagáltam minimális személyes szúrással: "Parttalan ez a vita, ha nem érted a különbséget aközött, hogy..." Arra törekszem, hogy nem kezdek személyeskedést és nem szólok vissza durvábbat mint amit kaptam. Ezt kiegyensúlyozottnak érzem a saját szabályaim szerint.

Válasz: "jól látszik, hogy az alapfogalmakkal sem vagy tisztában. Csak dobálózol itt olyan dolgokkal, amiket valahonnan hallottál, de valójában lövésed sincs, mit jelentenek. Már meg ne sértődj, de olyan vagy, mint egy indiai copy'n'paste huszár." Szerintem a független elemző is megállapíthatja, hogy ez megint eszkaláció ahelyett, hogy a felajánlott deeszkalációt elfogadtad volna. (Az, hogy nem emeltem a beszólás pofátlanságán, csak éppen alulról súroltam, de ezen az egyen kívül semlegesen fogalmaztam a deeszkaláció felajánlását jelenti meta-nyelven.)

Plusz:

"A baj az, hogy fogalmad sincs, hogy működik valójában a határellenőrzés (és a Rust fordító sem csinál mást, mint hogy csont ugyanazt az ellenőrző kódot generálja, mint a "-fsantize=address" hatására a gcc), nem tudod, mi a különbség a szintaktikai és szemantikai ellenőrzés között, és mégis próbálod osztani itt az észt."

Még egy beszólás ráadásul tárgyi tévedéssel egybefonva. Tehát kettő egy posztban és mindkettő durvább mint amire reagáltál, egyértelmű szándékos eszkaláció.

Az már csak hab a tortán, hogy erre a felkérésre: "Ha meg arra gondolsz, hogy egy másik változó címzésekor íródik felül, akkor fuss neki mégegyszer, hogy mi is az az ASAN és mire való, gugli a barátod! De elárulom, ezt az esetet észreveszi a C fordító statikus ellenőrzése és a valgrind is!" itt a válasz, és bár kb minden kommentre mondasz valami csúnyát, erre azóta sem jött válasz: https://hup.hu/comment/3035799#comment-3035799 Hogy lehet, hogy az ASAN figyelmét elkerülte, hogy az a pointer félrecímzésével a b értékét írtam felül? És valóban lehet ilyen példát csinálni Rustban vagy Javában? Esetleg a .NET valamelyik nyelvében? Azért nem lehet, mert alapvetően másképpen működnek mint a C és nem valószínűségi alapú az ellenőrzés bennük, hanem bizonyíthatóan korrekt. És az első lépés az kellene, hogy legyen, hogy megtanulod hogyan működnek ezek, mielőtt nagy mellénnyel gyalázkodásba kezdesz.

 

Egyébként tök örültem amikor írtál a rendszerbetöltőről, gondoltam na lám egy újabb érdekes arc megjelenik a hup-on, milyen király. Én igazán jóban akartam volna lenni veled, de egyszerűen elképesztő a viselkedésed. Szerk.: részemről továbbra is nyitott vagyok a deeszkalációra, ha hajlandó vagy abbahagyni a vagdalkozást.

Kiszámítható vagy, mint egy Csebisev interpoláció!

Te komolyan azt hitted, hogy ha megpróbálod a fejemre olvasni mindazt, amiben TE MAGAD vagy sáros, akkor majd megszeppenek vagy mi? ROTFL. Küldj be valamit, akkor talán komolyan vesznek majd az emberek, de addig csak nevetség tárgya maradsz.

Szerintem itt a HUP-on nagyon kevesen vannak, akik ilyen alacsony szintű programozással foglalkoznak

Na akkor a jó ég tudja hányadszorra ismét, a feladat megoldásához direkt NINCS szükség alacsony szintű programozásra! Ez a kiírásból több, mint egyértelmű, meg már jópárszor leírtam a gyengébbek kedvéért.

direkt NINCS szükség alacsony szintű programozásra

Ha látnám a C kódot, akkor talán még el is hinném ;-)

Ezek nekem mind nagyon alacsony szintű dolgoknak tűnnek:

a képernyőre VGA teletype módban kell írni (ASCII karakter (0x30 - 0x39) + attribútum (0x07 fehér) párosokból álló tömb a 0xB8000 fizikai címen a Video RAM-ban)

Ezek nekem mind nagyon alacsony szintű dolgoknak tűnnek

Mármint egy tömbbe írás neked már alacsony szintű programozának minősül? Ja, már mindent értek.

Gyk: ez egy teljesen mezei karaktertömb, annyi csak, hogy fix címen helyezkedik el, és felváltva ASCII karaktereket és attribútum bájtokat tartalmaz. Hogy miért ilyen? Tessék az IBM mérnökeinél reklamálni, nem én találtam ki!
De egy olyan programozási nyelvnek, ami állítólag leválthatja a C-t, nem kéne, hogy gondot okozzon írni bele!

Ha látnám a C kódot, akkor talán még el is hinném

Hidd csak el nyugodtan. A C forrás egyetlen fájl, két függvény, kevesebb, mint 50 SLoC, nincs benne inline Assembly, és csakis interfész függvényhívás történik benne (még lokális függvényt sem hív).

De nyugodtan megnézheted az Assembly referenciát is, nincs benne semmilyen alacsony szintű programozás, csakis interfész hívás. Sehol egy in vagy out utasítás, de még egy iret vagy lidt se; semmi, ami bárminemű alacsony szintű eszközhöz vagy CPU rendszeregiszterhez nyúlna.

Na, várj! Egy változónak a section meghatározása a C szabvány része? Eddig arról volt szó, hogy a nyelv szabványos eszközeit használhatjuk. C-ben úgy tudom, hogy sectiont használni nem része a szabványnak. Most akkor ezt lehet? Vagy C-ben tilos volna használni, mert nem része a szabványnak, viszont cserébe ott lehet olyat írni, hogy uint8_t * buffer=(uint8_t *)0xabcdef; De ezt Rust-ban nem írhatom le, mert ott unsafe-nek minősül? Viszont section specifikációt csinálhatok, mert az viszont része a szabványnak? (https://doc.rust-lang.org/reference/abi.html?highlight=link_section#the…) Bár az meg nyilván nem része a szabványnak, hogy mit kell kezdeni ezekkel a nevekkel, mert az meg platform specifikus, a linker szkript pedig nem Rust.

C-ben úgy tudom,

Te mit jössz már megint folyton a C-vel? Hajlandó lennél felfogni végre, hogy a versenyszabályokban és a feladat kiírásban nincs semmi C specifikus?

a linker szkript pedig nem Rust.

Tanulj már meg olvasni, ez már tényleg nagyon szánalmas, amit művelsz. Idemásolom:
bármilyen fordítási segédprogram megengedett, olyan is, amit külön kell telepíteni vagy saját fejlesztésű (például interface bindolók, fejléc generálók, linker szkriptek, binutils, make/mk/cmake/ant/scons/meson/ninja/azanyjakinyja stb.)

Csináld, ahogy akarod, csak adj már be végre valami megoldásfélét!

Mármint egy tömbbe írás neked már alacsony szintű programozának minősül? Ja, már mindent értek.

Sajnos nem értesz semmit és nem is vagy hajlandó elgondolkodni rajta sem, pedig leírtam már egy párszor, illetve el is olvashatnád az általad belinkelt oldalon.

A tömbbe írás természetesen nem számít annak, de egy fix memóriába írás vagy olvasás már annak számít. Az zavar meg, hogy szintaktikailag ugyanúgy néz ki egy saját tömbbe írás, mint a direkt memóriába írás. Ha C-ben és Rust-ban erre külön kulcsszó lenne (pl. read/write, in/out), akkor talán jobban megértenéd.

Namost a C++ szintakszisa valami borzalom. Persze megszokhato, de igazabol a feature-ok felet siman ki lehetne dobni kulonosebb kifejezokeszseg-vesztes nelkul (az utobbi par evben felivelo programnyelvek meg is tettek). A maradekot meg lehetne sokkal egyszerubben, olvashatobban is.

En probaltam es hasznaltam rust-ot, de igazabol nem vagyok meggyozve, hogy ez lenne a jovo -- ugyanaz a baj, mint a C++-al, egyszeruen a borrow checker egy kinszenvedes, totalisan lekorlatozza a developer productivity-t. Mondjuk reszelgetik rendesen, mar most is sokkal jobb, mint 3-4-5 eve volt, de meg 2x ennyi 'reszelgetes' kene neki, mire azt mondanam, kezd OK lenni.

A C-ben meg a 70-es evekbol visszamaradt stdlib a fo gaz. Azert ne 'char*' legyen a string igy anno 2024-ben! A szintakszis OK, egyszeru es kovetheto, de a komplett lib-et ugy, ahogy van, le kene cserelni. Meg a rust Rc/Arc/Box/... modellje is hasznos lenne, hogy 3 karakterbol GC-t es thread-safetyt kapjal. Valamint igy 2024-ben valami buffer overrun vedelem se artana, bar pointerekkel ez nehezkes, de legalabb az opcio jo lenne, stdlib szintjen akar.

Szoval nem, a C/C++ egyaltalan nem jo, viszont az is igaz, hogy a kihivoi se. Mindegyikre raferne egy massziv reszelgetes.

rossz helyen kopogtatsz, en profi vagyok c-ben.

de attol az meg szar.

a char*-al rengeteg gond van; a string ugye egy osszetett dolog, van ugye neki charset-je/encoding-ja, van (O(1) -ben lekerdezheto) hossza, meg nemi encapsulation se artana neki, mert ha valaki belebizgeral pointerrel, siman lehet az adott encoding-ban invalid a mar beolvasott es ellenorzott byte-stream.

Es akkor megerkezunk oda, ahol kb. az *osszes* mai nyelv/platform a stringet kezeli.

Amikor a C kialakult, ASCII tábla volt. Akár az is lehetne, hogy minden karakter 7 bites, az utolsó karakter lenne 0x80-nal OR-olva. Az strlen()-nel szemben nem tudok olyan követelményről, hogy O(1)-nek kellene lennie, bár ki-ki magában megfogalmazhat efféle igényt. A C-ben nem mellesleg az a jó, hogy minden nehézség nélkül kialakíthatsz saját struktúrát, ábrázolást string kezelésére. A hátulütője nyilván az lesz, hogy a fordító nem fog róla tudni, így a string konstansok megadása elég kellemetlenné válik.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Elnézést, hogy három és fél sorral - nyilván megjelenítéstől függ - terheltem drága életed idejét. Egyrészt elolvastad, mert írtál is rá, másrészt maradj a polfórumoknál, annak nyilván sokkal több értelme van, amikor bolonddal egymás testnedveiben csúszkálva nyilvánosan igyekeztek alázni egymást. ;) Azok a hozzászólások aztán igazán üdítők, sokat adnak a HUP közösségének életéhez.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A C-ben nem mellesleg az a jó, hogy minden nehézség nélkül kialakíthatsz saját struktúrát, ábrázolást string kezelésére.

meg a hash-nek, meg a list-nek, meg a set-nek, meg a ....

es akkor minden egyes projekt maganak mokanyol, tok jo, gyakorlatilag teljesen mas platform, atjarhatatlan.

ha leulsz egy python, java, go ele, akkor 10 percen belul atlatod; tudod, mire szamits, mit hol keress.

leulsz egy C ele, es szopsz, mint a torkosborz, mert az stdlib evtizedes elavultsaga miatt kvazi mindegyik total mas. ez mar most is igy van sajnos.

aztan mikor egy glib-es kodot kell atvinni qt ala, akkor meg nem megy, es kvazi ujra kell irni. tokjo.

ha leulsz egy python, java, go ele, akkor 10 percen belul atlatod; tudod, mire szamits, mit hol keress.

Francokat. Ez csak addig igaz, míg egy adott nyelven, egy adott framework-ön belül maradsz.

leulsz egy C ele, es szopsz, mint a torkosborz

Csak a zöldfülűek szopnak vele, a gyakorlott programozók áldják az eget, hogy a C pontosan úgy ábrázolja az adatokat, ahogy azok a memóriában vannak, és ezért nincs szívás, nem úgy, mint ha pl Python-ból kell egy összetett struktúrát átadni egy C++-ban írt függvénykönyvtárnak. Vagy csak egy NumPy eljárásnak. Vagy egy CPython wrapperelt eljárásnak.

Egyáltalán érted, miről beszélek? Fogadjunk nem. Segítek, az általad felsorolt nyelvek a típuskódot az érték mellett tárolják, így képtelenség másolás nélkül adatokat mozgatni közöttük. Hiába van CPython, JavaJNI, CGo, ezeknek mind az a hátránya, hogy nagy adatmennyiségre használhatatlanok, mert nem képesek címszerinti átadásra, hisz az általad megnevezett összes nyelv egyedi formátumban tárolja az adatokat a memóriában. Röviden: ezeknél a nyelveknél még esélyed sincs megúszni pont azt, amit a glib-qt-nál kifogásoltál, mert a nyelv része, nem tudod megkerülni. C-ben simán megoldható (tudnillik mind a glib, mind a qt egy függvénykönyvtár és még véletlenül sem része a nyelvnek).

Nagyon, nagyon, nagyon leegyszerűsítve egy konkrét példával: C-ben megteheted azt, hogy definiálsz egy struct-ot, majd egy-az-egyben betöltesz oda egy BMP képet mondjuk, és mindenféle konvertálás nélkül máris kezelni tudod. Az általad felsorolt egyik nyelvben sem lehetséges ez, mert az azokban definiált struktúra memóriaképe nem azonos a fájlbeli bájtoffszetekkel. Ezeknél a BMP struktúra mezőit külön-külön kell egyesével beolvasni és átmásolni a nyelvben definiált struktúra mezőibe, hogy azok használható Python, Java, Go stb. változók legyenek. Capisci?

az stdlib evtizedes elavultsaga miatt kvazi mindegyik total mas

Ja, bocs, most látom csak, hogy csillámfaszláma vagy. Oszt POSIX szabványról teccett-e már hallani? Nincs olyan, hogy "totál más stdlib", minden libc interfésze pont ugyanolyan, szabvány.

a C pontosan úgy ábrázolja az adatokat, ahogy azok a memóriában vannak

Itt elfelejtkezel a paddingról, amit a compiler automatikusan csinál. Egy C struct memóriabeli mérete, a tagok struktúrán belül pontos elhelyezkedése teljesen más lehet, mint amit te a programkódban látsz.

Itt elfelejtkezel a paddingról, amit a compiler automatikusan csinál. Egy C struct memóriabeli mérete, a tagok struktúrán belül pontos elhelyezkedése teljesen más lehet, mint amit te a programkódban látsz.

De gondolom ezt compiler direktívákkal lehet kapcsolgatni, alapvető dolog C-ben, hogy Te mondod meg, hogy a memóriában hogy legyen egy struktúra.

A compiler direktíva nem része a C szabványnak egyáltalán. Hordozható, pláne platform független kódot nem lehet vele írni.

 

Az meg, hogy valaki C kód helyett GCC/Clang/MSVC specifikus kódot ír, az hadd legyen az ő saját problémája.

Lényegtelen. Miért kellene módosítás nélkül azonnal helyesen lefordulnia más környezetben ugyanannak a forráskódnak? Az a lényeg, hogy platform- és fordítófüggően megoldható az, hogy a platformok közötti binárisok átadják az adatstruktúráikat egymásnak.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ja, bocs, most látom csak, hogy csillámfaszláma vagy.

Csak betévedtem ide, és olvasgatok, és tényleg jó szándékkal írom: ha valaki a kalapácsot ismeri jól (pl.: C-t), akkor hajlamos lehet mindent szegnek nézni.
Ellentmondásos érzést okoz, ha valaki elvileg mélyen ért egy területhez, de kommunikálni furcsa lekezelő stílusban kezd másokkal,
- nem jut eszébe, hogy nem csak annyiból áll a világ, amit Ő ismer, és lehet hogy a másiknak összegezve 1000-szer nagyobb tudása van.
- a másik még nem tart ott szakmailag, talán teljesen kezdő (nem jut eszébe, hogy Ő is tartott ott valamikor).

Efelett elsiklottam, bocs.

Egyrészt én biztos nem, mert nem én írtam azt a kommentet.

Másrészt elsiklottál a lényeg felett, hogy a való világban más nyelveken nem kell ~minden nagyobb projektben használható string kezelést csinálni, mert jó az, amit a nyelv tud.

(Meg afelett is, hogy más nyelveken is nyugodtan implementálhatok sajátot, ha nem tetszik. Nem hiszem, hogy létezik olyan kicsit is szélesebb körben használt nyelv, amiben ne lehetne kézzel biteket meg byteokat baszogtatni as-is)

Eleve ott bukik az egész versenykiírásod, hogy a Rust nyelvhez nem számítod hozzá az unsafe -et. Az unsafe a nyelv része, éppen azért, hogy minden olyat meg lehessen csinálni vele, amit a C-vel is, de úgy, hogy a 99,9%-a sokkal biztonságosabb, mint C-ben. ;-)

Another reason Rust has an unsafe alter ego is that the underlying computer hardware is inherently unsafe. If Rust didn’t let you do unsafe operations, you couldn’t do certain tasks. Rust needs to allow you to do low-level systems programming, such as directly interacting with the operating system or even writing your own operating system. Working with low-level systems programming is one of the goals of the language.

És unsafe használata esetén áll az összes általatok oly bőszen hangoztatott memóriabiztonság? Na ezért nincs benne a kiírásban.

De tudod mit? LEGYEN. Az interfész által biztosított függvényekre (és szigorúan csak azokra) használható Rust alatt az unsafe, de a többi függvényre továbbra sem.

Rendben! Ez eddig sem is volt másként!

Ehh, ki kell írnom, mert úgysem értitek: szarkazmus. A pointer használatától nem függ a fordító viselkedése, nem úgy, mint ahogy az unsafe kikapcsolja a borrow checkert. Egy C program, ami használ pointert meg egy, ami nem, nem fordul másként. A Rust esetében ez nem igaz, ott az unsafe használata MEGVÁLTOZTATJA a fordító visekedését. Egyébként meg hozzáírtam, hogy az interfész esetén használhattok unsafe-t, szóval tessék örülni és pofázás helyett egy megoldást beadni.

Mint laikus, én érteni vélem az unsafe használatának tiltását, hiába a nyelv része. Hozzáteszem, életembe nem láttan Rust kódot, a nyelvet sem ismerem, sőt, C-ben sem programoztam soha.

Viszont az eddigiekből lejött, hogy az unsafe "kiiktatja" a Rust egyik lényegi funkcióját, a védelmet. Egyszerűsítés!: az átlag programozó, ahogy megtudja, hogy kikapcsolhatja a védelmet, akkor bármi hiba esetén elsőre azt fogja tenni. Ha úgy működik a lomja, akkor nem keresi tovább a hibát, hanem úgy hagyja, gyakorlatilag megölve a védelmet nyújtó nyelv előnyét, az eredeti hibát pedig benne hagyva.

Pont ezért lettek népszerűek a nem típusos nyelvek, amikor bármit be lehet hányni bármilyen változóba, és amikor kiveszed, arra számítasz, hogy olyasmi van benne, amit szeretnél. Aztán ha mégsem, akkor majd a user észreveszi és hibát jelent. Típusos nyelvnél ez fordítási időben kiderül, csak úgy "lassabb" haladni, hogy mindig mindenféle bosszantó hibaüzenetekkel kell foglalkozni a fejlesztés során...

Azt gondolom, ez a kizárás oka, csak nincs minden egyes feltétel hosszas körmondatokkal megmagyarázva.

A Rust nyelv is olyan mint az összes többi: egy jó programozó munkáját segíti, egy rossz programozó meg pont ugyan olyan szar programot fog mindben írni.

Az unsafe nem az jelenti, hogy az adott programrész feltétlenül bajt csinál, hanem azt, hogy arra a részre nem tud a compiler garanciát adni. Mert garanciát akkor tud adni, ha a matematikai konstrukció amire a biztonság bizonyítása épül mindenütt be van tartva. Az unsafe-re a programozónak kell garanciát adnia, nagyjából ott van ahol C-ben lenne: vannak eszközei amikkel lehet hibás és hibátlan programot is írni.

Általában két céllal hozzák létre az unsafe dolgokat:

Egyik a teljesítmény növelése, amire nagyon ritkán, de szükség lehet. Azért mondom, hogy ritkán, mert a teljesítmény növelésére persze mindig szükség van, de többnyire nem ez a szűk keresztmetszet. Ritka az olyan program ami már annyira optimális, hogy már csak unsafe-fel lehet javítani rajta. De van ilyen és szükség van rá, akkor lehet.

A másik pedig a virtuális gép szabályainak nem megfelelő dolgok használata, ami lehet például egy másik nyelvbe belehívás, vagy perifériák memóriájának közvetlen írása. Ez az amire vélhetően a "versenyben" szükség volna.

Összefoglalva az unsafe azt jelenti, hogy a biztonságosságot a compiler és a runtime nem tudja garantálni, mert a bizonyítás logikájába bele nem férő módon történik a működés. De ettől még az a kód lehet biztonságos, csak azt a programozó egyéb módszerekkel kell hogy garantálja.

Nem hinném, hogy valódi probléma volna, hogy a kezdők értelmetlenül használnák az unsafe konstrukciót. Nem lesz attól egyszerűbb semmi, egyáltalán nem erről szól ez a kulcsszó. És ha mondjuk egy kernelt fejleszt valaki Rustban, akkor abban lesz fix számú unsafe, és azt ki lehet listázni a kódból és hozzá lehet mindegyikhez rendelni egy magyarázatot, hogy miért szükséges használni, és mi garantálja, hogy megfelelően működik. És az unsafe nem azt jelenti, hogy az egész programban deaktiválva vannak a védelmek, hanem csak pont abban a kis részben.

Az pedig továbbra is áll, hogy nyilván nem lesz egy kezdő szarja jó attól, hogy Rustban van, arra viszont mégis garanciát ad a nyelv, hogy a memória a virtuális gép szabályainak megfelelően fog működni. Tehát ha nem kap referenciát a kezdő programozó függvénye a b változóra, akkor annak az értékét nem tudja átírni semmilyen módon.

Egy c programban, ha 1 függvényt használsz, ami nem tuti, akkor megtörténhet, hogy felülírja az isLaunchingNuclearRocketImminent változó értékét igazra. Akkor is, ha a függvény feladata csak vonalkód nyomtatás lett volna valójában, de mondjuk valaki számok helyett betűket is írt a mezőbe, ami az átalakítás során overflowolt, és épp ez a változó csücsült ott. Ilyen Rustban nincsen, nem lehetséges. Ezt a hibaosztályt megszünteti a biztonságos memória menedzsment. De nem csak a Rustra igaz ez, számtalan nyelv régóta tudja, a Java és a .NET is ilyen volt már a kezdetektől (90-es évek), Quora szerint a BCPL volt az első nyelv, amiben biztonságos pointerek voltak.

>Azt gondolom, ez a kizárás oka, csak nincs minden egyes feltétel hosszas körmondatokkal megmagyarázva.

Ennek semmi értelme nem lenne, mert a funkcionalitás maga, például JavaScriptben megírva kb egysoros volna. Semmi értelme nincsen a probléma logikáján belül unsafe-t használni valakinek, aki tudja hogyan kell Rustot programozni. A tiltás értelme pontosan az, hogy a Rust unsafe nélkül csak Rustot tud hívni, hiszen ami kívül esik az ő VM-jén az számára nem safe. Tehát fából vaskarika unsafe nélkül a kírás. Olyan mint az, hogy "Vágjátok ki az erdő legnagyobb fáját! Ezzel a heringgel!" És ezt vagy tudja bzt és akkor nem fair a kiírás, vagy nem tudja, és akkor meg olyat kritizál amit nem ismer. Vagy lehet az is, hogy a C-be híváshoz nem kell az unsafe kulcsszó, de attól még az ugyanaz. Például Java-ban a native kulcsszó jelöli a JVM-ből kilépő hívást, amivel például C libraryt lehet hívni. Tehát nem unsafe a neve, de attól még az persze unsafe, mert a JVM nem tudja ellenőrizni, hogy odakinn ki mit hogyan fog felülírni.

Az unsafe nem az jelenti, hogy az adott programrész feltétlenül bajt csinál, hanem azt, hogy arra a részre nem tud a compiler garanciát adni.

1. nem is kell garanciát adnia a fordítónak, mivel az az interfész önmagában garantáltan safe. Ha a Rust nem lenne képes egy külsös safe függvény meghívására, az biza a nyelv hibája lenne. (Egyébként de, képes, mivel immutable a bemenet, de ezt is leírtam már vagy százszor)
2. az interfész esetében egyébként is megengedett az unsafe, mivel láthatóan nem tudjátok, hogy kell használni a Rust-ot, szóval ne gyere azzal, hogy nem lehet

A tiltás értelme pontosan az, hogy a Rust unsafe nélkül csak Rustot tud hívni, hiszen ami kívül esik az ő VM-jén az számára nem safe.

JUJJ. Egyrészről mint mondottam volt, az interfész esetében nincs tiltás, másrészről a Rust-ot nem is VM futtatja. Te valami iszonyatosan nagyon el vagy tévedve.

Most már meg kellett néznem a specifikációt, mert már idegesít, hogy én sejtem hogy minek kell ott lenni, mivel ismerek jópár nyelvet, de pont a Rustot nem. Te meg olyanokat mondasz, ami nem lehet ott. Szóval lássuk a specifikációt: https://doc.rust-lang.org/reference/unsafety.html

"Unsafe operations are those that can potentially violate the memory-safety guarantees of Rust's static semantics.

The following language level features cannot be used in the safe subset of Rust:

    Dereferencing a raw pointer.
    Reading or writing a mutable or external static variable.
    Accessing a field of a union, other than to assign to it.
    Calling an unsafe function (including an intrinsic or foreign function).
    Implementing an unsafe trait."

Tehát raw pointer access és a foreign function call is unsafe a specifikáció szerint. Ami nem meglepő, hiszen ezek kívül esnek a _virtuális gép_ hatáskörén. Mindegy, hogy valójában van-e runtime virtuális gép, a programozási nyelvek specifikációjában virtuális gépnek hívják a működés specifikációját, mivel ez nem egy létező gép, hanem virtuális, pont a nyelv specifikálja, de nincsen valódi gép ami így működik.

Az is mindegy, hogy kell-e ezekhez unsafe kulcsszó, a lényeg, hogy a specifikáció egyértelműen megjelöli, hogy a Rust VM szempontjából ezek unsafe konstrukciók. Vicces egyébként, hogy épp egy fejezettel előtte van az inline assembly, ami nyilván szintén unsafe, de itt elfelejtették újra megemlíteni: https://doc.rust-lang.org/reference/inline-assembly.html

Összességében a Rust specifikációja nem látszik annyira kidolgozottnak, mint például a Java nyelvé (ez az amit régebben mélyebben olvasgattam), de nagyjából az van benne amire számítottam.

Na most akkor döntsd el légy szíves, hogy konkrétan az unsafe kulcsszó az ami tiltott, vagy az unsafe konstrukciók általában? Egyébként leírtuk, hogy a videó RAM elérés az, amihez szükséges a "raw pointer" használata, ha ezt tiltod, akkor nem lehet megcsinálni és visszajutunk a róka és a daru vendégségéhez. A versenykiírás legyen először egzakt, addig nem állnék neki vadul kalapálni a pályaművet.

Na most akkor döntsd el légy szíves, hogy konkrétan az unsafe kulcsszó az ami tiltott, vagy az unsafe konstrukciók általában?

Már leírtam konkrétan, görgess egy kicsit feljebb. Semmi sincs tiltva, ami a megoldáshoz feltétlenül szükséges!

videó RAM elérés az, amihez szükséges a "raw pointer" használata

Egyáltalán nem szükséges.

Azt azért lássuk, hogy ha igaz, amit írsz, és ehhez tényleg ki kell kapcsolni a memóriaellenőrzést, akkor nincs jogotok arra verni a nyálatokat, hogy hű, de jó a Rust, mert van benne memóriaellenőrzés!
Van benne memóriaellenőrzés, csak épp muszáj kikapcsolni (Te állítottad ezt, nem én). Pontosan az ilyen marketing bullshitekre akartam rámutatni ezzel a kiírással!

ps: egyébként tényleg nem kötelező a video RAM eléréshez a "raw pointer", használhatnál helyette pl. sima mezei tömböt és linker szkriptet. De ez csak egy lehetséges megoldás a sok tucatnyi közül.

Baszki, a tortenelem tenyleg megismetli onmagat.

Tobb mint negyed evszazaddal ezelott, a legutolso programozo versenyen azt nyertem, hogy a Zengo nevu kocsmaban Ujpesten egy hetig (vagy egy honapig? fene tudja mar) ingyen ihattam az osztalytarsam kontojara.

A feladat a sima "Egy sakktablan hany kiralynot tudsz elhelyezni anelkul, hogy barmelyik utne barmelyiket?" volt. A szempont a kod tisztasaga es a lepesek szama volt. A kollega Turbo Pascalban irta, en Borland C++ nyelven.

Az remlik, hogy rekurzivan irtam, de volt valami csalas, mert bizonyos esetekben tobbet leptem vissza, mert elore bejeloltem, hogy kesobb mely mezok nem lesznek jo. Vagy valami hasonlo, mar nem emlekszem.

Na mindegy, a lenyeg, hogy a C/C++ versus akarmi vita mindannyiunkat tul fog elni, es meg az ukunokaink is ezen fognak veszekedni!

Haha, a jó öreg klasszikus backtrack?

Tényleg jó lenne, ha valóban ismételné magát, de sajnos a Te versenyeddel ellentétben - ahol volt egyáltalán mit összehasonlítani -, itt most csak siránkozás és szánalmas kifogások érkeznek bármiféle értékelhető megoldás helyett :-( :-( :-(
Bár sejtettem, hogy ez lesz, de azért szívem mélyén azt kívánom, bárcsak rendes verseny lenne ez is. De van még egy hónapjuk, talán valaki rámcáfol addig.

(Egyébként felőlem jöhet Pascal megoldás is, bár az nem egy agyonhypeolt nyelv, mint a Rust, és annál sosem volt kérdés, hogy megoldható-e benne ez a feladat. De ezektől függetlenül is jó lenne látni mégegy öreg motorost! Rég használtam Pascal-t, de legutóbb is pont egy rendszerprogramot kalapáltam össze fpc-ben demonstráció gyanánt.)

En mar reg nem programozok "nagyban", mostansag 95% bash, mert rendszergarazda vagyok, konkretan evek ota nincs semmilyen IDE a gepemen.

De egyebkent a memoriakezeles es a leakeles elkerulese mar 25 eve is tema volt. 2000 -ben keszullt vizsga munkam egy olyan C++ osztaly volt, ami a himem.sys -re tamaszkodva egyfajta virtualis memoriat biztositott az ot felhasznalo kod szamara. Lokalis valtozokent kellett peldanyositani, de a sok (lokalis) peldany egy static valtozon keresztul tartotta egymassal a kapcsolatot. Az adott peldanyt hasznalva lehett rajta keresztul rohadt nagy meretu tombot, listat, fifot, lifot foglalni, es hasznalni. DOS alatt lehetett igy akar tobb MB-os adatszerkezeteket egyben kezelni. A josag az volt benne, hogy ha kileptel a lokalis valtozod ervenyessegi tartomanyabol, akkor a destruktor felszabaditott mindent, amit eddig foglaltal, ergo esely sem volt leakelni, ha rendesen hasznaltad.

Persze ez csak egy technikai bemutato volt, hiszen addigra mar volt vedett mod, es mindenki Windows 98 -at hasznalt, igy a DOS szukebb keretei a kutyat sem erdekeltek, de azert jo mulatsag volt megirni.

Fura, hogy evtizedekkel kesobb is ugyanazok a problemak koszonnek vissza, amelyek csak reszben vannak jol megoldva. A Java GC jo elgondolas, de a finomhangolas azert be tud kavarni. Irtad, hogy Ada-ban irtal kodot, nos, egy volt munkahelyemen olyan "biztonsagos" Ada kodot kellett kezelnem, ahol nagyjabol minden valtozohoz kulon tipust hoztak letre, hogy biztosan ne lehessen kisebbet-nagyobatt beletolteni mint amire a kolto gondolt. Ez elmeletileg jo, csak gyakorlatilag a fene se tudta fejben tartani, hogy a tobb tucat integer valtozobol melyik milyen range ertekekkel rendelkezik. Agyf4szt is kaptam tole rendszeresen. Nem sokkal kesobb meg a dolog masik oldala jott szembe ugyanannal a cegnel, amikor C# programozoi sapkaban allandoan olyanokat kellet irnom, hogy if (alma != null) alma.valami(); mert a hatam borzongott, hogy mi az isten ez a kupleraj, hogy kerulhet ide egy null ertek, es ha null, akkor miert nyeljuk le csendben a nem teljesen jo mukodest, ahelyett, hogy megallitjuk a szemet be, szemet ki folyamatot?

Szoval nem csak nyelvek, de a programozasi szokasok, modszertanok is tudnak annyira masok lenni, hogy ihaj. 

Szerkesztve: 2024. 03. 08., p – 20:32

Én nem tudok ilyet írni, viszont nem tudom lesz-e belőle valami (remélem igen), szeretem az ilyen kódpornókat. :)

"Sose a gép a hülye."

Elsőre ez a kép jutott eszembe. Sajnos lehetséges, hogy nem mérhető, hogy melyik nyelv a legjobb. Túl komplex, mennyi mindentől függ. Ott van a nyelv megtanulásához szükséges idő, a kódolási idő, stb...

Sajnos lehetséges, hogy nem mérhető, hogy melyik nyelv a legjobb.

És milyen jó, hogy sosem ez volt a kérdés, és hogy ennek a versenynek egyáltalán nem is ez a célja!

Ott van a nyelv megtanulásához szükséges idő, a kódolási idő, stb...

Ezek mind egyénfüggő dolgok, semmi közük a nyelv kifejezőerejéhez. Milyen jó, ezen szempontok egyike sem szerepel a kiírásban!

Onellentmondasba utkoztel, de gondolom valami kis szemelyeskedessel es onmagad piedesztalra emelesevel majd kimagyarazod magad: :D

"Elegem lett a sok nagyszájúból, ezért úgy döntöttem, lehetőséget adok nektek a gyakorlatban is bizonyítani,  hogy valójában a gyakorlatban egyik csodanyelv sem képes leváltani a C-t"

:D

Ha jól értem, egy nagyon fontos dolgot felejtettél ki az értékelési renszerből: a befektetett időt.

Mikor szarul voltunk fizetve ez nem volt releváns, de most igen.

Ha jól értem, akkor csak kötözködsz, mivel még egyáltalán nincs is mit értékelni. Küldj be előbb egy megoldást, aztán majd visszatérünk rá!

A befektetett időt egyébként szándékosan hagytam ki, hogy a programozói készségek ne számítsanak bele, csak a nyelv. Nekem a C megoldás kb. 15 percet vett igénybe, az Ada kb egy órát (mert vétettem egy hibát, és debuggolni kellett). Ezzel úgysem képes versenybe szállni senki itt a HUP-on, ezért nem is lenne fair, úgyhogy kihagytam a szempontok közül, és egységesen 1 hónapot adtam a megoldásra.

A teljesség kedvéért az egész versenykiírásra ráfordított idő:
- megtervezni a szabályokat kb. 2-3 óra volt (ezért ennyi, mert közben több nyelv dokumentációját is átnéztem ellenőrzés végett),
- a betöltőt elkészíteni kb. fél óra, ebben benne van az ELF és PE/COFF formátum lekezelése, a megszakításvezérlő és a PIT felprogramozása is. Ehhez felhasználtam korábbi projektek forrását, azért ilyen kevés.
- az Assembly referencia megoldást elkészíteni kb. 10-15 perc volt (ez nem számít ugye bele a versenybe, de a betöltő teszteléséhez szükség volt rá, hogy legyen egy jól behatárolt baseline)
- további 1 óra volt a tesztelés és debuggolás qemu és bochs virtuális gépeken. Bár a kiírás csak qemu-ra szól, egy másik virtuális gépen is leteszteltem a biztonság kedvéért.
- plusz kb. 10-15 perc volt megírni a HUP topikindító bejegyzést.

Szumma: kb. 1 munkanap, tokkal-vonóval. (csütörtökről péntekre éjjel álmodtam meg a versenyt, pénteken kb. délelőtt 10 óra magasságában álltam neki, és a poszt fél ötkor került ki a HUP-ra.)

Érdekesség: a tesztelés során előjött egy Clang bug MS fastcall ABI használata esetén (parancssori kapcsoló figyelmen kívül hagyása), ezért módosítottam az interfészt, és hozzáadtam a függvény által használt lokális változók méretét paraméterként az iretq() függvényhez, hogy egészen biztosan bármilyen nyelvből, bármilyen fordító által generált kód esetén használható és probléma nélkül meghívható legyen.

Én csak azért jöttem, hogy a HUP nagypofájú "programozói" ^ hogyan szerepelnek majd a megmérettetésen 🍿

trey @ gépház

Úgy tűnik a hozzászólásokból, hogy a csapat egy jelentős részének - ide értve magamat is - már megkoptak vagy soha nem is voltak elég mély ismereteik ahhoz, hogy egyáltalán értsék, hogy mégis mi a nyavaja történik vagy kéne történjen itt pontosan, mi fán terem a rendszerprogramozás. Ennek ellenére persze egyesek meglehetősen vehemensen osztják az észt :)

Nem programoztam rustban, még csak nem is nagyon foglalkoztam vele, szóval gondoltam doksi jóbarát, nézzük mit tud az unsafe:

https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html

Aztán ismerős volt, már idézett valaki ebből.

Rust needs to allow you to do low-level systems programming, such as directly interacting with the operating system or even writing your own operating system. Working with low-level systems programming is one of the goals of the language.

 Ebből a felületes kezdeti bevezetőből nekem két dolog jön le:

1. Alacsony szinten programozni rustban usafe nélkül nem lehet, azért van, hogy ha valaki ilyet akar, akkor tudjon.

2. Kifejezetten cél, hogy lehessen unsafe-et használni, ez egy üzemmódja a nyelvnek adott feladat esetében és akkor a programozó tökönszúrhatja magát ha akarja.

Tehát vannak dolgok amiket a nyelv tervezői szerint Rustban is deklaráltan veszélyesen csinálnak az emberek. Namármost akkor megintcsak két dolog lehet.

1. Amiért szidják a C-t, hogy szar meg nem biztonságos, az igazából zömében nem az alacsonyszintű rendszerprogramozás, hanem a magasabb szintű pl. OpenSSL, GTK (még mielőtt nekem esnének, hogy ezek nem is szarok, ezek csak példák magasabb szintű felhasználásra), ahol azért használják mert egy C formájú kalapáccsal oda is oda lehet baszni.

2. Azokat a feladatokat amiket meg lehet oldani Rusttal safe módban nyilván meg lehet írni C-ben is megfelelő eszköztámogatással éppen olyan biztonságosan. Akkor az a kérdés, hogy kényelmesebb-e Rustban dolgozni?

 

Nekem elsőre a Rust szintaxisa elég fura, de lehet csak szokni kell. :)

Szerintem jól látod a problémát. Amikor a tanult kolléga rendszerprogramozásról beszél, akkor ő lényegében nagyon alacsony szintű, kb. periféria programozásra gondol, miközben a rendszerprogramozás ennél jóval bővebb: ebben benne benne van a kernel és a hozzá kapcsolódó szolgáltatások (scheduler, file system, networking, stb.) és sokszor még olyan közös könyvtárak, melyekre utána a magasszintű nyelvek építenek (például kriptográfia műveleteket/titkosítást megvalósító könyvtárak, ui könyvtárak, web szerverek, adatbáziskezelők, stb.)

"Operating systems, device drivers, BIOS and other firmware, compilers, debuggers, web servers, database management systems, communication protocols and networking utilities are examples of system software."

https://devopedia.org/systems-programming

És igen, alapvetően két okból írták ezeket a rendszerprogramokat C-ben: (1) mert ehhez értettek, ezt ismerték (kalapács-szög) (2) mert nem volt alternatíva. 

ő lényegében nagyon alacsony szintű, kb. periféria programozásra gondol, miközben a rendszerprogramozás ennél jóval bővebb

Pontosítsunk: ennél a versenynél azért nem vettem ide az általad felsorolt bővebb halmazt, mert egy számláló növeléséhez és kiírásához nincs szükség ezekre. Ugyanezen okból biztosítottam a betöltőt, hogy még PIC + PIT eszközmeghajtót se kelljen írni, és a CPU funkciókat is beburkoltam magas szintről hívható eljárásokkal, hogy a függvénykönyvtárak függőséget is kiiktassam.

És igen, alapvetően két okból írták ezeket a rendszerprogramokat C-ben: (1) mert ehhez értettek, ezt ismerték (kalapács-szög) (2) mert nem volt alternatíva.

Egy kis pontosítás a (2)-eshez: továbbra sincs alternatíva. Eddig egyetlen megoldás sem érkezett, csak picsogás, siránkozás, kifogások áradata. Amíg az ellenkezőjére nincs bizonyíték, addig továbbra is fel kell tennünk, hogy a Rust alkalmatlan a feladatra.

Történelmi érdekesség: mind a Pascal, mind az Ada bizonyítottan rendszerprogramozási nyelvek, amik valós alternatívái lehettek volna a C-nek, de valamiért mégsem váltották le azt.

Mint ahogy a tanult kollégák elmondták, ez a trade-off: bizonyos részeket nem lehet memory safe-re írni, mert nem. Viszont, ha a kódom 99%-át memory safe-re tudom írni, akkor csak a maradék 1%-ra kell koncentrálnom hogy ott ne legyen probléma. 
 

https://doc.redox-os.org/book/ch01-06-why-rust.html

Csakhogy ez Rustban íródott, itt nincs egyetlen külsős függvény sem! Ha a kód 99%-a unsafe mentes lenne, nem szólnék semmit, de ez az állításod hazugság. Gyakorlatilag a függvények több, mint 80%-a unsafe!

Konkrét ellenpélda: indokold meg, ennél függvénynél például miért kell az unsafe-t, ha az egyszer nem használ memóriát egyáltalán és csakis belsős Rust függvényeket hív! Ha igaz lenne, amit a Rust dokumentáció ír, akkor itt nem szabadna, hogy szerepeljen az unsafe.

pub unsafe fn acknowledge(irq: usize) {
    match irq_method() {
        IrqMethod::Pic => {
            if irq < 16 {
                pic_unmask(irq)
            }
        }
        IrqMethod::Apic => ioapic_unmask(irq),
    }
}

(Abba, hogy mennyire elképesztően nem hatékony, és hogy a programnyelvtől függetlenül is konkrétan hibás ez a kód, inkább bele se menjünk.)

Gondolom mert továbbhív egy másik függvénybe amelyik ugyanúgy unsafe, ami a nap végén gondolom valami C-ben implementált cuccot hív (a fájl elején ott van a use crate::). 

Egyébként 513 unsafe van a teljes kernelben, legalábbis a kereső nekem annyit adott vissza. Ennél felteszem egy "kicsivel" több függvény van.

Gondolom mert továbbhív egy másik függvénybe amelyik ugyanúgy unsafe, ami a nap végén gondolom valami C-ben implementált cuccot hív

Na akkor ízlelgessük kicsit, amit itt írtál.

1. továbbhív egy unsafe függvénybe, ezért ennek is unsafe-nek kell lennie: ezzel gyakorlatilag azt mondod, hogy effektíve lehetetlen safe Rust kódot írni, merthogy a hívási lánc végén minden alacsony szintű függvény unsafe.
2. C-ben implementált cuccot hív: nocsak, nocsak, mégegy beismerő vallomás, hogy a Rust nem alkalmas a C leváltására? Ez a mondat minden kétséget kizáróan ezt jelenti.

Igen, valószínűleg a Rust nem tudja 1-az-1-ben leváltani a C-t, viszont kellően le tudja csökkenteni azon helyzeteket, ahol C-t (vagy pl. assembly-t) kell használni. Ez pedig lehet, hogy bőven elegendő, és már előrelépés. Neked nem, neked jó lesz a C, másnak meg igen.

viszont kellően le tudja csökkenteni azon helyzeteket, ahol C-t (vagy pl. assembly-t) kell használni.

Az állítás ezen részét még mindig nem látom bizonyítottnak.

Mit ahogy azt sem, hogy hogyan lehetséges egyáltalán safe Rust írása, ha
1. állításotok szerint nem lehet mindent safe-ben megírni
2. a raw pointer unsafe például, és mivel ez nélkülözhetetlen bármilyen memóriaallokátor írásakor, így a memóriallokátor sem lehet safe
3. safe-ből nem hívható unsafe, csak unsafe-ből, tehát minden dinamikus memóriát használó eljárás, ami a memóriallokátort hívja, muszáj, hogy unsafe legyen
4. ha minden memóriafoglalás magával vonza, hogy unsafe, akkor hogy is lehetséges safe Rust kódot írni?

A baj itt az, hogy ez az egész egy humbug, és a hosted Rust alkalmazások csakis azért lehetnek "safe"-ek, mert az std felrúgja a nyelv saját szabályait, és ellenőrizetlenül, csakazértis safe-nek van bevasalva ez a függvénykönyvtár, holott ha pusztán natív Rust-ban akarnád implementálni, akkor képtelenség lenne ezt megvalósítani a fent sorolt okok miatt.

Igen, de ez az unsafe hív safe-t irány sosem volt kérdés.

A gondot az okozza, hogy az alacsony szintű függvényeknek muszáj unsafe-nek lenniük, így tehát az azokat hívó magas szintű függvényeknek is (ez a safe hívna unsafe-t irány). Mégis, valahogy azt hazudják, hogy a magas szintű függvények safe-k lehetnek, holott ez a Rust saját szabályai szerint sem lehetséges.

Ha tényleg betartjuk a Rust dokumentációban foglalt szabályokat, akkor nyilvánvaló, hogy lehetetlen safe Rust programot írni. Ez csakis úgy lehetséges, ha felrúgjuk a specifikációban foglalt safe nem hívhat unsafe-t szabályt, másként nem. Ezzel pedig pont a lényegét veszíti el a safe kulcsszó.

A gondot az okozza, hogy az alacsony szintű függvényeknek muszáj unsafe-nek lenniük, így tehát az azokat hívó magas szintű függvényeknek is (ez a safe hívna unsafe-t irány). 

Ez nem így van, csak maga a hívásnak kell unsafe-ben lennie, az egész hívó függvénynek nem, az lehet safe.

Az általad belinkelt, de még mindig el sem olvasott doksiban ez is benne van, lásd 19-6 lista. ;-)

Ez nem így van, csak maga a hívásnak kell unsafe-ben lennie, az egész hívó függvénynek nem, az lehet safe.

Állításod szerint ez érvényes safe Rust kódnak minősül:

fn hu_ez_aztan_baromira_safe() {
  unsafe {
    ...
  }
}

Köszönöm, hogy felhívtad erre a figyelmem, álmomban sem gondoltam volna, hogy ennyire szar lenne a Rust! Ezek szerint a Rust memóriaellenőrzési garanciája konkrétan egy fabatkát sem ér.
Ez tökéletes bizonyíték arra, hogy a Rust nem is memóriabiztonságos nyelv!

Disclaimer: nem értek a lovakhoz :)

Szerintem itt félreérted a koncepcióját a rustnak.

Miután minden hardver közeli funkció, és egyéb külső függvény alapvetően "unsafe" (nem tudja a fordító bizonyítani a biztosságát a kódnak - mert nem látja hogy mit tartalmaz) ezért  unsafe-be kell tenni.
Viszont aki az adott függvényt/függvénykönyvtárat írta "vállalja" hogy safe a kód, így a ráépülő kódok safe-k lesznek, és azon már működnek a nyelv-szintű garanciák.

Szerkesztve: 2024. 03. 10., v – 00:05

Mivel nagyon unalmas már a siránkozásaitokat és kifogásaitokat hallgatni, a továbbiakban csak azokat veszem komolyan, akik be is adnak valamit.

Addig is mégegyszer, nyomatékosan:

- a repóban egyetlen egy C forrás sincs.
- a feldatatban semmi C specifikus nincs. Egy számláló növelése és kiírása a képernyőre nem szabadna, hogy gondot okozzon bármilyen rendszerprogramozási nyelven.
- bármilyen nyelv, bármilyen fordító, bármilyen szkript, bármilyen segédprogram használható a lefordításhoz.
- megoldásnak egy ELF vagy PE/COFF formátumú futtatható binárist kell prezentálni, ami egybefűzve a formátumnak megfelelő betöltővel fut qemu-n.
- beadás határideje 2024. április 8. 00:00:00 UTC.

Ennyi.

Én még talán annyit vettem volna bele a kiírásba, hogy valaki ne AI-val írassa, de az meg elég ellenőrizhetetlen mondjuk.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Kicsit játszottam vele, ráengedtem a ChatGPT-t (az ingyenes verziót), ha már az NVIDIA meg a Microsoft szerint is az AI fog programozni. Nem mondom, hogy teljesen értem mindegyiket. Mert, bár érdekelnek a programnyelvek, sokkal megismerkedtem, egyikben sem írtam programot.

Megírattam vele Free Pascal, ADA, Forth (VFX), Rust, Go és Zig nyelven is. Már csak le kellene tesztelnem a generált kódokat, hogy egyáltalán működőképesek-e. Sajnos ennyire nem vagyok otthon programozásban, hogy magam is meg tudjam írni őket.

Természetesen nem rontom el bzt kolléga kihívását! Figyelmesen követem, hogy valamelyik babzsákfejlesztő felveszi-e a boxkesztyűt!?

Megírattam vele Free Pascal, ADA, Forth (VFX), Rust, Go és Zig nyelven is

Nagyon szépen köszönöm, hogy vetted a fáradságot és legeneráltattad ezeket a megoldásokat!

Már csak le kellene tesztelnem a generált kódokat, hogy egyáltalán működőképesek-e.

Ha esetleg feltennéd valahova a forráskódokat, akkor simán lehet, hogy lesz itt jelentkező, aki szívesen segít Neked lefordítani őket, mert ez a teszt már önmagában is roppant érdekes! (És egyébként még a versenyszabályoknak sem feltétlenül mond ellent, azt írtam, bármilyen segédprogram használható. Kicsit sántít ugyan, mert nem a fordítási környezet része, de vegyük úgy, hogy az MI is egy fordítási segédprogram ez esetben!)

Amint a fordítással megvagy, akkor csak annyi dolgod, hogy eléfűzöd a betöltőt és az így keletkezett fájlt átadod a qemu-nak:

cat boot_elf.bin programod.elf > disk.img
qemu-system-x86_64 disk.img

Elvileg ennyi letesztelni.

A tisztánlátás végett annyi kérésem lenne csak, hogy két kört csináljunk. Első körben próbáljuk meg lefordítani pontosan azt, amit generált. Második körben meg azt, amibe esetleg kézzel bele kellett javítani, hogy forduljon, vagy hogy helyesen működjön.

Összevetve a beküldött kódokkal, nincs a helyzet magaslatán. Most csak Rust megoldást kértem tőle, de olyan dolgokat használ, ami ki van kötve, hogy nem lehet. Busyloop-ban várakozik, inline assembly-t használ, a loader asm forrását is megkapta és a struct-ot is, de a PIT inicializálást megírja újra. :-)

De amúgy jó ugráltatni!

Rust szemszögéből minden külső függvény unsafe

Ha ennyire sírtok, hogy külsős függvény így-úgy unsafe, akkor megírhatjátok ezt a négyet unsafe nélkül natív, belsős Rust függvényekben is!

- load_idt: betölti az IDT-t. A megadott buffert a függvény nem írja és még csak nem is olvassa, csupán csak betölti a címét a CPU-ba
- enable_interrupts: a CPU megszakítások engedélyezve jelzőbitjét állítja be
- disable_interrupts: a CPU megszakítások engedélyezve jelzőbitjét törli
- iretq: lenyugtázza a megszakításvezérlőben az IRQ-t és visszatér a megszakításkezelőből

Választhattok:
1. vagy használjátok az interfészt és ezeknél az unsafe-t
2. vagy nem használjátok az interfészt, Rust-os függvényekkel implementáljátok le, de ekkor nem használhattok unsafe-t

Na kérem, ez egyszer és mindenkorra eldőlt, az összes picsogó, aki szerint C-re lett kiírva a verseny meg ilyenek, jobb, ha bocsánatot kérnek!

Befutott az első Rust megoldás. Nincs nightly rustc-m, így letesztelni nem tudtam, de nekem teljes és nagy valószínűséggel helyes megoldásnak tűnik!

Akkor nem szívatom magam a ChatGPT által adott megoldással. Játszós környezetben telepítettem Rust-ot és próbáltam a ChatGPT által adott válaszokból megoldani, de ezidáig nem született megoldás. Mondjuk egyelőre ez annyit jelent, hogy prompt engineer-ként sem fogok tudni elhelyezkedni egyelőre. :-D

szerk.: az első pályaművet letöltöttem és kipróbáltam. Ahogy sejtetted működik. De gyanítom ez nem is volt kérdéses. A beküldő kódját megnézve nekem az jött le, hogy hasonlóan hozzád, érti is amit csinál. Nem úgy mint a többi szájkaratés. De mivel én csak ugatom a témát, a véleményem nem túl releváns.

A "többi szájkaratés", aki nem tud ilyen alacsony szinten programozni, az éppen azért szájkaratézott érvelt, hogy az ilyen megoldásokat is el kelljen fogadni.

Úgy látszik, hogy mégsem "szájkaraté" volt, hanem megalapozott érvelés, amit bzt, a fenti hozzászólása alapján, el is fogadott.

Ma délután két óra alat eljutottam Free Pascalban egy 90%-os megoldásig. :) Az interrupt handlerrel van valami gebasz, amúgy megy. Olybá tűnik mintha vagy az IDT táblaban a setup vagy a meghívása félremenne. De még reszelem. De az már biztos, hogy az x86_64 rendszerprogramozási/ELF tudásom hiányos hozzá, nem az eszköz. Szóval grat mindenkinek h. felértek egy Pascal szintjére. :P

Amúgy ez remek játék, csak az a bajom, hogy rohadt specifikus dolog, amihez leginkább azt kell ismerni, hogy a programozási nyelvedet hogy lehet a kőbróken by design és legacy all the way down x86_64 architekúra köré csavarni. Attól hogy ez megy, még nem biztos h. nagy alkalmazások fejlesztésére alkalmas a nyelv. Ráadásul ez a szintű interrupt handling még a nagy OS-ekben is többnyire assemblyben van írva, pedig azok C-ben készültek. :)

De amúgy ettől függetlenül élvezem ezeket a kihívásokat, szóval elszívok még vele, csak ezzel nem dől el semmi, nem bizonyít semmit.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

És meg is van - jó kis compiler bug, így jár aki a Git main-en él... :D Az IDT összerakásakor a compiler félreoptimalizál valamit. Egyelőre wörkaround befigyelt, majd kifixelem a compilert is, vagy anyázok az x86_64 port karbantartóinak... De mindenesetre most már szépen megjönnek az interruptok a handlerbe.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Így: https://github.com/chainq/langcontest-pas

Ja a bináris (ELF) amúgy 664 byte. Ebből 256 byte csak a 4db ELF section header, amik nélkül 408 byte-ról beszélünk. Ami kisebb mint a kézzel írt assembly 425 byte-ja... :) Tudom, sántít az összehasonlítás, de azért vicces. Még van egy hónapom, talán majd kiszopom hogy hogy lehet olyan ELF-et gyártatni, amiben nincsenek sectionök.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Köszönöm! Hozzáadom a Pascal megoldásodat!

amihez leginkább azt kell ismerni, hogy a programozási nyelvedet hogy lehet a kőbróken by design és legacy all the way down x86_64 architekúra köré csavarni

Igen, a verseny célja az, hogy a nyelv kifejezőerejét teszteljük. Mivel a C egy rendszerprogramozási nyelv, minimum elvárás, hogy a többi versenyző is képes legyen erre, emiatt lett a feladat egy rendszerprogram.

Attól hogy ez megy, még nem biztos h. nagy alkalmazások fejlesztésére alkalmas a nyelv

Szerintem egy rendszerprogramozási nyelv alkalmazásprogramozásra is alkalmas kell legyen, hisz utóbbi a szűkebb funkciókat igénylő halmaz. (Lásd pl. Pascal alkalmas mindkettőre, ugyanakkor például a Java csak alkalmazásfejlesztésre való, rendszerprogramozásra nem. Ezzel szemben nem ismerek olyan nyelvet, ami csak rendszerprogramozásra való, ellenben alkalmazásfejlesztésre nem használható.)

Ráadásul ez a szintű interrupt handling még a nagy OS-ekben is többnyire assemblyben van írva

És itt is. Direkt azért biztosít interfészt a betöltő, hogy ez ne legyen probléma.

De az a baj, hogy egy x86_64 rendszerprogramozás az bármiben gusztustalan, még C-ben is. Ez kb. olyan mintha azzal tesztelnénk melyik (emberi) nyelv mennyire szép, és milyen "kifejező ereje" van, hogy milyen jól lehet benne kínrímeket írni. "Mint Zuzuval beszélgetni. Enyhén szórakoztató, de leginkább fájdalmas." Ebből a szempontból a C az különösen olyan, hogy meg lehet írni benne egy csomó mindent amit másban nem, nyolc rétegű makróhalommal meg pragma-túltengéssel, csak minek. 2 sor inline assembly többet ér, még akkor is ha az már "nem a nyelv része". (És most itt nem akarok Pascal vs. C-be kezdeni, mert azt tényleg minek, az a vonat min. 35 éve elment.)

Mindegy. A szentimentumot értem a newschool nyelvek ellen, de attól még továbbra is úgy gondolom, hogy ez nem egy jó teszt. Pluszban, a Rust-nak mintha lett volna egy embedded working groupja, amiben különösen erre mentek rá, hogy hardware közeli dolgokra, igaz főleg mikrokontrollerek és társaik programozására jó legyen. Szóval az ilyen tesztekkel az a baj, hogy ahogy az idő halad, egyre extrémebb és extrémebb dolgokkal kell majd "tesztelni", hogy mennyire nem jó semmire. És őszintén, már egy x86_64 low-level interruptkezelés is elég extrémen ronda...

Én legalább bevallom hogy szubjektív okokból nem kedvelem a Rust-ot, pl. szerintem ritka gusztustalan a szintaxisa, de mivel mások meg a Pascalról gondolják ezt, ezért nem fogunk összeveszni, inkább tisztelem felebarátaim elmebaját és kész. Meg a szokásos overhype miatt, miszerint ez majd megoldja az afrikai éhinséget, a globális felmelegedést, feltalálja a mindenség elméletét, meg a toronyórát lánccal is, csak én már elég öreg vagyok hozzá, hogy emlékezzek legalább 3 ilyen ciklusra szakmánkból. Én még emlékszem, amikor a Java volt a jövő, abban írtak OS-t, meg a sok okos elhitte hogy "van garbage collector, ezért nem lehet memory leaket csinálni". Aztán egész jó pénzt kerestem abból úgy egy évtizedig, hogy az ilyen fejlesztők kódjait fixelgettem. :) Már kezdődik ez a trend a Rust-nál is, most pl. a Microsoft kiadta a Rust-ban Windows-ra írt sudo klónt, aminél feltüntették h. mekkora sekureti stonks, mert hogy Rust, na egy hozzább értő szét is kapta mint floki a lábtörlőt, mert "az ellen nem véd" ha valaki elbassza az ellenőrző logikát és emiatt az egész cucc a nagyon memory-safetyvel együtt simán bypassolható. Szóval ja. Nekem ez a fajta hívő-hozzáállas, és a kritikai gondolkodás hiánya, ami nem tetszik egy csomó newschool nyelvben, és a Rust ebból az elsőszámú példa. De majd kinövöm, gondolom. A Java-t meg a Pitont is utáltam eleinte, aztán mikor végül valamit dolgozni kellett benne, akkor csak ment... Mondjuk hobbiból továbbra sem megyek egyik közelébe sem...

Legalul a processzor úgyis csak a goto-t meg a pointereket ismeri. Hogy ki mivel akarja kábítani magát, hogy ez nincs így, majdnem mindegy. :) Köszönöm, hogy elmondhattam, leültem.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Miért hagyta el bzt a barátnőjét? Mert nem C melltartót hord.

Szerkesztve: 2024. 03. 11., h – 13:34

Oregon, golgota, asch, enpassant

Kiderült, hogy a vádaskodásotok teljesen alaptalan volt. Tényleg nem érzitek úgy, hogy illendő volna egy bocsánatkérés?

Nem vádaskodtam egyetlen egy hozzászólásomban sem.

Azt nem éreztem fair-nek, hogy az unsafe-et nem engeded meg, így megoldhatatlanná válik a feladat Rust-ban.

Erről írtam minden hozzászólásomban.

Kezdetben elfogadtad, hogy az interfésznél lehessen, végül pedig azt is, hogy memória direkt írásánál is. Így én elértem a célom, Rustban is meg lehet oldani a feladatot.

bzt, nem kellene bocsánatot kérned, hogy kezdetben kizártad mondvacsinált okokra hivatkozva a Rust-ot?

Egyébként én elfogadom bocsánatkérésnek azt, hogy végül is elfogadtad az érveimet.

Te írtad: Nem gondolnám, hogy közülük van egy is, aki hajlandó lenne ezt Rustban megírni.

Azt nem éreztem fair-nek, hogy az unsafe-et nem engeded meg

Ami valójában nem fair, az az, hogy azzal jöttök, azért jobb a Rust, mert memóriabiztos, miközben a legeslegelső dolog, amit itt követeltetek, az az, hogy unsafe-el kikapcsolhassátok a memóriabiztonságot...

Egyébként meg még mindig nem adtál be semmilyen megoldást, csak pofázol. Nem bántásból mondom, csak ténymegállapítás.

Ami valójában nem fair, az az, hogy azzal jöttök, azért jobb a Rust, mert memóriabiztos, miközben a legeslegelső dolog, amit itt követeltetek, az az, hogy unsafe-el kikapcsolhassátok a memóriabiztonságot...

Úgy látom, hogy még mindig nem érted. Megpróbálom a beadott Rust kód alapján elmagyarázni.

impl Application {
    const fn new() -> Application {
        Application {
            timer: 0,
            counter: 0,
        }
    }

    fn write_number(&self, number: usize) {
        let vga = 0xb8000 as *mut u8;

        for i in 0..4usize {
            let digit = (number / 10usize.pow(3 - i as u32)) % 10;
            unsafe {
                vga.add(i * 2).write(digit as u8 + 48);
            }
        }
    }

    fn pit_tick(&mut self) {
        self.timer += 1;
        if self.timer == 100 {
            self.timer = 0;
            self.counter += 1;
            self.write_number(self.counter);
        }
    }
}
Ez a lényegi része az alkalmazásnak, a többi az interfésszel tartja a kapcsolatot.

Ebben minden safe, kivéve az az egyetlen sor, ami írja a direkt memóriát. Ha az nincs megengedve a Rust-nak, akkor nem lehet megírni Rustban a feladatot.
Itt még tovább lehetne csökkenteni az unsafe r észt, hiszen a a vga.add(i * 2) is kitehető, illetve a digit növelése 48-cal.
Tehát így a legkevesebb az unsafe rész:

  vga.add(i * 2);
  let digit_ch = digit as u8 + 48;

  unsafe {
      vga.write(digit_ch);
  }

Egyáltalán nem. Sőt!

Egyrészt most már, hogy van pályamű - amit majd én is meg fogok nézni magamnak, eddig nem láttam -, mostantól mindannyian mondhatjuk, hogy a Rust leválthatja a C-t, hiszen még számlálót is lehet rendszerprogramként megvalósítani, arra is alkalmas.

Másrészt erre továbbra is várom a választ: https://hup.hu/comment/3035799#comment-3035799 Ha megnézed még a dátuma is jóval előbbi mint a versenykiírásod. Tehát az óvodai vagdalkozás szabályai alapján előbb neked kell megfelelned a kihívásnak, addig meg sem szólalhatnál, ameddig erre nem adsz kimerítő választ.

Utána az következik, hogy bocsánatot kérsz a hangvételed miatt, ami egyrészt nincs megalapozva tudással, de még ha tudással megalapozott volna, akkor sem volna jogos egy fórumon vélemények miatt "anyázni". Ha megnézed eltérő véleményekre, de csupa normális hangvételű posztra reagálsz rendszeresen "anyázással". Nem kéne!

Utána pedig töredelmesen le kell írnod, hogy tévedtél mind a Rust rendszerprogramírása alkalmassága kapcsán, mind pedig a C memóriabiztonság ellenőrző technikáinak a működési elve és megbízhatósága kapcsán. Mi pedig többen is próbáltunk rávezetni téged a megfelelő szakszavak és pointerek biztosításával, amit figyelmen kívül hagytál. Nekünk mindannyiunknak igazunk volt, te viszont az arroganciád miatt nem tudtad befogadni az igazságot. A magam részéről ezt mind meg tudom bocsátani, ha írásban kéred.

Ha jól értem a kiírás valóban olyan volt, hogy a Rust unsafe konstrukciói nélkül nem megoldható, de utólag jóindulattal elfogadtad az unsafe pályaművet. (Nem néztem még meg, a többiek reakciói alapján mondom. Majd megnézem ha lesz időm.) Ez szép a részedről, de előre honnan tudhattuk volna? A kérdéseinkre adott válaszod alapján jogosan következtettünk arra, hogy nem fogod elfogadni. De jogos volt elfogadni és örülök is neki. Mivel az üzenetváltásainkban nem erre utaltál, ezért nincs miért bocsánatot kérnünk.

A linker szkriptre nem gondoltam, hanem a pointert akartam volna beírni közvetlenül a kódba. Ez az egy, amiben tévedtem. A tervezés első fázisaiban - azaz a lehetőségek felmérése közben - elkövetett tévedésért nem szokásom bocsánatot kérni.

És ezek után sem tartozok bocsánatkéréssel azért, amiért még pénteken is pénzér dolgoztam (tudom, lámerség pénteken dolgozni), és péntektől-hétfőig sem foglalkoztam a _te_ hobbiprojekteddel, hanem a családdal töltöttem a hétvégét. Mínusz az online trollkodás meg egy kis saját hobbiprojekt persze :-)

Kedves óvodás vagdalkozó!

https://hup.hu/comment/3035782#comment-3035782
Ez korábbi, mint a Tiéd, és mivel nem válaszoltál rá, így ha komolyan veszed magadat, nem is lett volna jogod feltenni a comment-3035799 kérdést, ugyebár. Ide is idemásolom: És a Go meg a Rust meg a többi csodanyelv hogy is veszi ezt észre? Mutass egy konkrét példát

Ha jól értem a kiírás valóban olyan volt, hogy a Rust unsafe konstrukciói nélkül nem megoldható

Csakis azért szerepelt az unsafe tiltás, mert Ti állítottátok, hogy a Rust egy memóriabiztos nyelv! Aztán a legelső dolgotok az volt, hogy elkezdtétek habzó szájjal követelni, hogy ki lehessen kapcsolni a memóriabiztonságot Rustban...

És mégegyszer: az interfész teljesen safe, nem nyúl a memóriához, a load_idt-nek átadott buffert nemhogy nem írja, de még csak nem is olvassa, mindössze betölti a címét a CPU-ba.

A "csodanyelvek" nem észreveszik, hanem kizárják azt az esetet, hogy a-ra kap referenciát egy metódus és mégis b-t írják felül. És leírtam a választ, nem maradt megválaszolatlanul.

>az interfész teljesen safe

Nem vitattam, hogy el van-e baszva. Hanem azt állítottam, hogy a Rust technológiája szempontjából unsafe, mert nem ő bizonyítja, hanem a programozó vállal rá garanciát. Már párszor leírtuk ezt is.

Az óvodás vagdalkozást te kezdted ilyenekkel, hogy nem pofázhatunk vagy hasonlók - nem keresem ki szó szerint. Csakis azért reagálok a stílusodban, mert másképp erre képtelenség. Még az óvodás vagdalkozásnak is vannak szabályai, és az első megválaszolatlan kérdés még mindig neked van szegezve nem nekem. Egyelőre te vagy aki itt nem pofázhat. Majd ha megválaszoltad a fentebb linkelt kérdést.

A "csodanyelvek" nem észreveszik, hanem kizárják azt az esetet

:facepalm: és mégis hogy tervezik kizárni annélkül, hogy előbb észrevennék...?

a-ra kap referenciát egy metódus és mégis b-t írják felül

Hát a Rust biztos nem. Csak pár ellenpélda:
https://github.com/rust-lang/rust/issues/106868
https://github.com/rust-lang/rust/issues/75577
https://github.com/rust-lang/rust/issues/72933
https://github.com/rust-lang/rust/issues/70078
https://github.com/rust-lang/rustfmt/issues/6107
...stb.
Ezekben az a közös, hogy a Rust fordító egyáltalán nem vette észre, hogy másik változóba ír a generált kód, és még csak trükkös referenciára sem volt szükség hozzá. Sima lokális változó korrupció. Pár issue-t workaroundoltak, de olyan is van bőven, ami a mai napig megoldatlan.

Tudod, itt az igazán nagy baj nem az, hogy memóriakorrupció előfordulhat bármilyen nyelven. A baj az, hogy míg ezzel a C programozók tökéletesen tisztában vannak és odafigyelnek rá, addig a Rust programozók bedőlnek a marketing bullshitnek, hogy memóriabiztos, és a hamis biztonságérzetük miatt egyáltalán nem figyelnek erre.

Valóban nem mentél bele, hanem Te magad kezdted azt a bizonyos ún. "cicaharcot" ;-)
És még mindig nem tisztáztad, hogy mit is kifogásoltál pontosan, csak vagdalkoztál akkor is, meg most is.

Én megelégszem egy bocsánatkéréssel, nincs harag.

Rust 'megoldás' szerzője.

 

Rust proponens vagyok, de szerintem ez az ötlet hogy van valami csodanyelv teljesen null. A nyelveket problémák megoldására csinálták, C-ben nem fogsz web komponenseket írni, JS-ben nem fogsz interruptokat kezelni. Rust előnye szememben hogy igaz nem lehet 100% teljesen korrekt safe programot írni, de ha egy random memóriacímre kell írnod akkor igazolnod kell hogy igen, tudom mit csinálok, engedj írni ide, ha felrobban én basztam el valamit. DE programokat amiket írok a 3 nagy operációs rendszeren futnak, unsafe részét már megírták és sok szem van rajta hogy korrekt legyen, így amikor én használom mint api biztos lehetek benne illetve típus szinten nem is engedi hogy például invalid referenciát adjak egy függvénynek, ha a safe subset alatt maradok.

C-ben nem fogsz web komponenseket írni

Ööö, jelen, én rendszeresen csinálom... (bár annyira sosem voltam elborult, mint pl. aki webfórumot írt Assembly-ben, én általában csak JSON REST API-kat szoktam C-ben implementálni, de végfelhasználói HTML-re is akadt már példa). A lényeg, hogy simán lehetséges, és bizony vannak, akik csinálják is.

JS-ben nem fogsz interruptokat kezelni

Ez viszont valóban, még elméletben sem lehetséges, mivel interpretált szkriptnyelv.

A hozzászólásod többi részével tökéletesen egyetértek, és külön köszönöm, hogy kulturáltan érveltél. Igen, az hogy ellenőrzött lib-eket használ az ember valóban rengeteget számít, ez tény, de ez éppúgy igaz a többi nyelvre is. Lehet érdemes lenne egy alkalmazásfejlesztői versenyt kiírni majd, amibe már beleszámítana a lib ökoszisztéma is.

> JS-ben nem fogsz interruptokat kezelni

Ez viszont valóban, még elméletben sem lehetséges, mivel interpretált szkriptnyelv.

 

javascript mikrokontrollerre:

http://johnny-five.io/

 

Kifejezetten interruptra pelda:

https://gist.github.com/rwaldron/769068fbbc9b433768dd

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Szerkesztve: 2024. 03. 11., h – 17:57

Elgondolkodtam, hogy lehetséges-e egyáltalán értelmes szabályokat kiírni alkalmazásfejlesztésre, amennyiben a libek is beleszámítanak.

Hát nem egyszerű. Ha a libek számát nézzük, akkor biztos, hogy a C magasan nyer, de elsősorban azért, mert már nagyon régóta használják, és minden más nyelvvel is garantáltan kompatíbilis.

A libek minőségét pont a libek hatalmas száma miatt nehéz meghatározni, mert tuti kimarad pár. Ugyancsak ennek köszönhető, hogy nincs egységes lista róluk (bár volt próbálkozás, pl. CPAN), és hogy natívan kell telepíteni őket (pl. debian és ubuntu alatt csak hozzácsapod a csomagnév végéhez, hogy "-dev", és a többit az apt megoldja neked). Ez jó, mert nincs szükség külön hekkelésre meg infrastruktúrára, gond nélkül simul a rendszerbe, rengeteg a mirror; ugyanakkor rossz is, mert minden disztrónak saját lib listája van emiatt. (Például ugyanaz a Perl xml parser lib elérhető sima csomagban is a disztrómon, ami feltesz manpage-t meg mindenféle doksit, meg CPAN alól is, ami viszont nem telepít manpage-t. Melyiket vegyük figyelembe? Python-os libek esetén ugyanezek a kérdések merülnek fel.)

Ha a dokumentáltságot akarjuk nézni, akkor megint hasonló a szitu: nem minden libnek könnyű megtalálni a doksiját, és soknak nincs, vagy rossz. Ugyanakkor az is tagadhatatlan, hogy a valaha létezett legjobb lib doksik mind C libekhez tartoznak.

Itt külön kiemelném a Microsoft-ot, ami általában csapnivaló doksikat készít, de az MSDN-je annyira szenzációs, hogy azt komolyan tanítani kéne, hogy tessék, így kell lib doksit csinálni. Minden paraméter külön-külön részletesen el van magyarázva, bőven megtolva infókkal meg linkekkel, és ha valami nem is lenne világos, egyértelmű, merre kell tovább keresgélni. A különösen neccesebb hívásoknál, meg a kezdők által gyakran felmerülő kérdésekre meg mindenhol konkrét C nyelvú példaprogramokat tartalmaz a dokumentáció, még akkor is, ha triviális (például ilyeneknél).

A másik tökéletes példa az ugyancsak kiváló minőségű SDL dokumentáció. Na, így néz ki egy jó lib doksi. Részletes paraméter leírás, linkek, példaprogramok dögivel. (Sajnos épp webmotort váltanak, így előfordulnak benne kissebb formázási bökkenők, de ezeknek semmi köze a doksi minőségéhez, ez technikai probléma).

C# esetén nem rendelkezem kellő tapasztalattal, de ismerősök szerint a .NET dokumentáció ugyanilyen jó minőségű, már ami a Microsoft által biztosított libeket illeti, de a többi 3rd party libé már csapnivaló. De ezt csak mások véleményére alapozva írom, semmiképp sem mérvadó, nincs személyes tapasztalatom.

Java esetében hasonló a helyzet, de ott még tovább bonyolódik a dolog a rengeteg szerteágazó middleware miatt. Ott sem hiszem, hogy könnyű lenne értékelni a libeket megbízhatóság vagy épp dokumentáltság szerint, mivel nagyon nagyon sok van, ráadásul sokminden middleware specifikus, így kérdéses, mit is vegyünk szó szerinti Java libnek.

...stb.

Szóval ha valaki ki akar írni egy alkalmazásversenyt, akkor hajrá, támogatom! Én biztos nem fogok, mert nem érzem azt, hogy igazságos szabályrendszert tudnék felállítani hozzá.

C# esetén nem rendelkezem kellő tapasztalattal, de ismerősök szerint a .NET dokumentáció ugyanilyen jó minőségű, már ami a Microsoft által biztosított libeket illeti, de a többi 3rd party libé már csapnivaló

A doksi 99%-a peldaerteku, de tipikusan van egy-ket kevesbe frekventalt resze, ahol csak ki van hanyva a netre, hogy milyen tagja vannak egy-egy osztalynak, aztan szevasz. Koszi, ki vagyok segitve, az IDE ugysem mutatja meg. (De.)

Tipikusan ilyen peldaul, amikor WMI-n keresztul kellett nemreg kinyernem Hyper-V guestek bizonyos adatait, mar-mar a kuruzslas kategoriaban. Abban sem vagyok teljesen biztos, hogy amit talaltam hozza, az valodi feature, vagy csak egy bug, amit egyszer majd patch-elnek, es akkor mehet a kodom a kukaba. A masik ilyen WTF moment nemreg a secpol lekerdezese volt. Annak konkretan az lett a vege, hogy az alkalmazasunk lefuttat egy secpol.exe-t a hatterban, es osszeszedi annak a fajlba mentett kimenetet. Ha nem sikerul, akkor szopo van, error, try again later.

Osszessegeben azert inkabb szeretettel gondolok ra, mint nem.

A doksi 99%-a peldaerteku, de tipikusan van egy-ket kevesbe frekventalt resze, ahol csak ki van hanyva a netre, hogy milyen tagja vannak egy-egy osztalynak, aztan szevasz. Koszi, ki vagyok segitve, az IDE ugysem mutatja meg. (De.)

Igen, pontosan ezt mondták akiket megkérdeztem. Sajnos ez a forráskommentekből generálunk használhatatlan doksit, nyelvtől függetlenül is jellemző :-(

Ha a referencia implementációt nem számoljuk bele, akkor összesen 4 megoldás van eddig.

Érkezett egy Rust és egy Pascal megoldás (ezeket már fel is tettem a repóba), én meg viccből csináltam egy olyan C változatot, ami egyáltalán nem használ pointert, mivel egyesek reklamálták, hogy ne lehessen pointer C-ben.
Mind multiplatform, kikéve a Rust-ost, de az is csak mindössze egyetlen egy kulcsszó miatt (feature(abi_x86_interrupt)) nem fordul. A kód összes többi része architektúrafüggetlen, ezért szerintem az is elfogadható multiplatformnak.

Lehet már maga a kiírás is olybá tűnt, hogy bzt magas lóról beszél. Érthető. Az én meglátásom szerint neki van mire. Valóban tudja mit csinál. Viszont arra a gőgre, amit pl. a Rust hívők képviselnek, szerintem teljesen valid reakció volt a kiírás. Egyszerűen bicskanyitogató a nyomulás amit művelnek. Próbálják minden eszközzel legitimálni az új csillámfaszlámás programozási nyelvüket úgy, hogy közben keresztes hadjáratot indítanak a régi, már jól bevált, bizonyított nyelvek ellen. Közben a "nagy" tech cégek, és még a fehér ház is bekajálja az evangéliumot. Gondolom ezért lehetséges mert már ezeken a helyeken is ugyanezek a bokavillantós, babzsákfotelben nevelkedett, szójalattét szürcsölő soydev-ek mondják az áment. Igen, a Rust-ra van kihegyezve, mert rájuk a legjellemzőbb. Aztán ha valaki kicsit a mélyére néz a dolognak, tulajdonképpen semmivel sem különb az egész, mint amit már régen kitaláltak. Csak az egész nyakon van borítva egy rózsaszín cukormázzal.

Egy valóban jó programozó bármilyen nyelven tud jó programot írni. Egy szar programozónak meg adhatsz bármilyen szuper biztonságos nyelvet, akkor is tökön lövi magát. Ettől a Rust sem fogja megvédeni.

És pont az ilyen bootcamp-ben nevelt kódhuszároknak köszönhetjük, hogy lassan egy szájbatekert paint programhoz is 128 magos processzor kell, Terabájt RAM, meg a világ összes háttértára nem elég. Hogyan írnak ma is egy floppy lemezen elférő, teljes értékű operációs rendszert grafikus felülettel és még pár játék is belefér?

En barmikor szivesen beszallok a bootcampek ekezesebe, de azert ne essunk at a lo tuloldalara, nincs igeny arra, hogy tomegevel keszuljenek az egy floppy-n elfero teljes erteku OS-ek, jatekokkal. Ne az legyen mar a szakmad merceje, hogy mennyi haszontalan dolgot tud eloallitani. Ha ilyen kihivast keresel, akkor demoscene versenyekre, vagy C obfuszkalo kihivasokra kell nevezni.

Ma ott tart ez az iparag, hogy a digitalis analfabeta nagymama minden problema nelkul lathatja a masik orszagban elo unokajat, meg bele tudunk nezni az emberek testebe kivulrol, sot, mar lassan muteteket levezenyelnek az orvosok egy masik foldreszrol, de ez lofasz, mert a sok rohadt bootcampes ingyenelo nem ir eleg floppy-s OS-t. :)

Szerintem nem estünk át a ló túloldalára. Azok estek, akik a mai operációs rendszereket és programokat írják. Ez egy sarkos példa volt, amire nagyon ráfókuszáltál. Nem azt akartam vele érzékeltetni, hogy legyen sok egyfloppy-s rendszer. De állítsuk már meg ezt az végtelen pazarlást! És erre jó példa a mai operációs rendszerek és programok. Én az ellentétre akarom felhívni a figyelmet, mindegyik működő operációs rendszer, grafikus felülettel! Az egyik elfér egy floppy-n, a másiknak lassan több tíz GB nem elég. Nem beszélve arról, hogy tulajdonképpen nem tudod használni a számítógépedet, mert az operációs rendszer zabálja fel az összes erőforrást. Holott nem az lenne a feladata (szinte láthatatlanul), hogy kezelje és elérhetővé tegye az erőforrásokat?

Ugyanarra. Persze.

Tehat a floppy-n is elfero operacios rendszerrel tudok olyat csinalni, hogy az uj kolleganak kozvetlenul a nagykerbol kuldom ki a ceges laptopot, amit kivesz a dobozbol, beirja a ceges accountjanak adatait, es az OS feltelepit mindent, amire a munkajahoz szukseg lesz?

Vagy mondok egyszerubbet, a floppy-s OS plug&play mukodik ~minden forgalomban levo hardverrel?

Mutatsz kerlek ilyenre peldat?

Mire való egy operációs rendszer?

A gyakorlatban arra, hogy tudjak a szamitogepemmel penzt keresni es/vagy szorakozni. Tudom, hogy letezik egy szakmaibb, de teljesen irrelevns definicio is.

Nem tudom miért akadt be a floppy, úgy látom ennél tovább nem látsz. Egy példa volt arra, hogy létezik akkora méretű operációs rendszer is, grafikus felülettel, amivel működik a számítógép. Nyilván annyira én sem vagyok zokni, hogy azt gondoljam, majd a legújabb grafikus motoron futó Doom menni fog rajta.

Az OS minek telepítene fel bármit is?

Azt a ~minden forgalomban lévő hardvert hanyagoljuk. Még Linux alatt igaz is lehet, de Windows-t hagyjuk, és még a driver-ek sem indokolják a gigás telepítéseket.

Nem tudom miért akadt be a floppy, úgy látom ennél tovább nem látsz.

Nem a floppy a lenyeg. Te mondasz olyanokat, hogy az 1-2 megas OS, meg a 10-20 gigas (melyiknek kell 20 giga az OS-nek? mindegy is) "ugyanazt tudja" "ugyanarra jo". Felolem lehet floppy helyett network boot is, tokmindegy.

Te mondasz olyanokat, hogy az 1-2 megas OS, meg a 10-20 gigas (melyiknek kell 20 giga az OS-nek? mindegy is) "ugyanazt tudja" "ugyanarra jo". Felolem lehet floppy helyett network boot is, tokmindegy.

Ugyanazt tudja (a saját kontextusában = OS). A nagyobbik nem ugyanazt tudja (általánosságban), mint a másik, mert van még "bónuszként" odabaszva melléje úgy kb. 85-90%-nyi minden más junk, amire amúgy a kontextusban (= OS) semmi szükség nincs, és az igen nagy részére a felhasználók döntő többségének igazából semmiféle igénye nincs. Viszont kvázi rájuk van erőszakolva (ne sánta, itt egy púp! jeligére), mert nem opcionális, nincs triviális módja annak, hogy a felhasználó ne kérje - nyilván elvileg le lehet vakarni ezeket, de az egyrészt erősen feketeöves próbálkozás, meg aztán vagy eltörik valahol egy NULL-pointer miatt valami, vagy nem (való életbeli példa: ha elkezded egy Win10-ből kidobálni a csomagokat, el fog jönni az a pont, amikor valamelyik fül a Gépházon megnyitáskor crashel. Mert a nagytudású redmondi programozók a büdös életben nem tesztelték a szoftvert minimál környezetben).

Megerteni sokan megertettek, legfeljebb nem ertettek vele egyet.

Te olyan definiciokon rugozol, ami a gyakorlatban semmit nem jelent. Tegnap telepitettem egy RHEL-t, valami 780 csomag volt az alaptelepites. Most akkor ebbol mennyi az operacios rendszer, es mennyi a userland? Vegulis mondhatod, hogy nem kell networking az OS-be, meg nem kell text editor, csak akkor hasznalhatatlan lenne a gep, amikor eloszor bekapcsolod.

Azt probalom a fejetekbe vesni, hogy igen, lehet 1-2 megas, vagy akar meg kisebb OS-t gyartani, van is olyan (nagyon-nagyon szuk) terulet, ahol ertelme is van, de ez nem valamifele kovetendo benchmark. Attol meg, hogy mondjuk egy desktop Linux elfoglal ugy 2 GB tarhelyet, attol nem lesz szuksegszeruen "rossz". Ez bullshit. Tovabb nem is akarom ragozni.

Nem, nem az OS zabalja fel a gepek eroforrasait, hanem a rajta futo programok. Es jo is ez igy, mert azert vannak az eroforrasok. Majd a cpu scheduler meg a virtual memory manager szepen lekezeli ezeket. 

Masreszrol tenyleg megneznem azt az 1.4 MB-os operacios rendszert aminek van grafikus felulete, tudja a bloetooth-ot, wifi-t, kezeli a 3D kartyat es szepen futtatja az UE5-os jatekokat, dolby hanggal.

Most megneztem az en kernelem a Linuxomon 78MB-ot eszik. Kurvara nem ferne ra egy floppy-ra. De kulonosebben nem zavar, hogy a programok amiket hasznalok hasznaljak a cpu-t es memoriat, mert igy tudok zenet hallgatni, mikozben futnak a k8s-es tesztjeim local-ban es meg ide irogatok is. Persze ha nem dolgoznek, nem hallgatnek zenet a bt fulesemen az internetrol es nem irogatnek ide, akkor lehet eleg lenne ket floppy-nyi is a kernelnek. Igaz akkor hasznalni sem tudnam a gepemet, de micsoda mini rendszerem lenne :D

(mivelhogy grafikus feluletu OS-ekrol beszeltel es nem egy ioT szenzor lapkarol)

Jah, a Linux is egy szar, mert nem fer mar ra egy floppy-ra :D

Bluetooth, wifi meg a dolby hang nem indokolja a több tíz gigás rendszert. Szerintem a 3D kártya sem. Az UE5 hogy is jön az operációs rendszerhez újfent?

Pontosan, az nem baj, ha a programok használják a cpu-t és a memóriát, de ne az oprendszer, a háttérben futó több száz folyamattal, amit senki nem kért, hogy fusson.

nem is az a kerdes mennyire bullshit vagy sem (amugy nem, mert rengeteg alkalmazasfuggo kod van ezekben, ami pont azok mukodeset biztositja es/vagy performacia miatt kell bele), hanem, hogy ezek a valo eletben hasznalt modern megoldasok. pont le*om, hogy egy szoftver pl. 3kilobyte vagy 300MB, mert a hattertartol a memoriaig a 300 MB is <0.1s alatt jut el egy modern rendszeren. mikozben az atlag human autovezeto reakcioideje ~0.5-1 sec...

Persze, és ebből jó eséllyel 634MB a szemét (installer, tray app, csoda updaterek, mindenféle nem kellő utilityk), és 0.47MB (az inf, a cat meg max 1-2 sys fájl) a lényegi driver. Ezért nem telepítünk installerrel soha drivert.

"Sose a gép a hülye."

hat, rohadtul nem :) ahogy irtam is fentebb sw-hw-kompatibilitasi meg API verziok tomkelege miatt ekkora, plusz jar hozza a szoftver, amivel a kedves paraszt kezelgeti a hardveret meg kihasznalhatja a kepessegeit.
mukodik anelkul, csak akkor egyreszt mi lesz azokkal a pistikekkel, akik arra elveznek, hogy mennyi mindent be lehet allitani! :D vagy epp azokkal, akiknek tenyleg be is kellene valamit.

Valami nagyon speciális cuccról beszélhetsz, mert nem emlékszek, hogy találkoztam valaha is olyan hardverrel, amihez ha volt adott OS-en belül driver és működött rendesen, akkor ne lehetett volna az OS valamelyik saját tooljával, vezérlőpultban, vagy mittomén akárhol beállítani valamit, legyen az akár hangkártya, nyomtató, bluetooth, wifi vagy akármi.

"Sose a gép a hülye."

te se lattal meg modern VGA-t vagy ismered legalabb erintolegesen a funkcioit? ertem en, hogy a 80x25 text mode-hoz nem kell driver meg szoftver... de ahhoz nem kell 10-20+kkk tranzisztor sem.
osszekeveritek az out-of-the-box "valahogy" mukodiket meg leszarjatok, hogy a kedves user ki tudja-e a hasznalni a termek adta funckiokat szoftver nelkul.

nincs igeny arra, hogy tomegevel keszuljenek az egy floppy-n elfero teljes erteku OS-ek, jatekokkal

A baj nem is az, hogy nem képesek tömegével ilyeneket gyártani, hanem az, hogy ha akarnának se tudnának még mutatóba se.

És abban sem lennék olyan biztos, hogy ne volna igény. Persze nem floppy és nem OS, de szerintem nagyon is lenne igény a kicsi, gyors, jól átlátható programokra a mai világban, amikor még a fájlböngészőt is teleszarják telemetriával és kémprogramokkal.

Biztonsági szempontból nagyon nem mindegy: elrejteni valami kártékony kódot egy 100 Megás programban gyerekjáték. Ugynazt elrejteni 100 Kilobájtos kódban művészet, már ha lethetséges egyáltalán. (Emlékezz csak, régen, amikor 64K volt a BIOS ROM maximális mérete, még vírus sem volt rá, bezzeg ma, amikor több megás a firmware, még egy párhuzamosan futó, lehallgatásra kifejlesztett operációs rendszert is elrejtettek benne (!).)

Arról nem is beszélve, hogy a mai sérülékenységek több, mint 99%-a nem is abból ered, hogy ne írnák meg jól a programot, hanem abból, hogy nem is akarják jól megírni, nem is képesek jól megírni, mert minek, csak berántanak dependency-nek valamit, máshoz nem is értenek. Tipikus példa erre bármelyik electron "alkalmazás" (de a fentebb emlegett IME-t sem csak a CIA és az FBI tudja használni, hanem bármilyen rosszakaród is hozzáférhet, mert azt is hozzá nem értő vérpistikék követték el). Aztán persze később rendszerint kiderül, hogy a berántott dependency már eleve lukas volt, mint a szita. Erről több tanulmány is született már, és azt is megmérték, hogy a kifejezetten a dependency-ket célzó támadások száma 2017 és 2019 között majdnem a duplájára, 88%-kal emelkedett. A helyzet annyira súlyos, hogy már a nem épp IT centrikus újságok, mint pl. a Forbes is többször foglalkozott a témával.

Felhasználói élmény szempontjából sem mindegy, hogy 1 perc bebootolni a gépet vagy csak 25 ezredmásodperc, vagy hogy egy alkalmazás azonnal indul, vagy perceket kell várni rá. Ez direkt kihat a munkáltatók zsebére is, egyszer érdemes lenne összeszámolni, hogy egy átlagos irodában egy átlagos napon mennyi fizetett idő megy el arra, hogy az alkalmazottak várnak a számítógépre. Gyanítom a GDP nem elhanyagolható részét teszi ki a valóságban. (Arról nem is beszélve, hogy egy programozót rendesen kiképezni drága ugyan, de egyszeri költség, míg a veszteség kevésnek tűnik, de folyamatos és általános.)

Szóval nekem az a véleményem, hogy az igény továbbra is fennáll, csak most már nem a hardver limitációk indukálják, mint régen, hanem manapság az átlátható, biztonságos és hatékony megoldás miatt lenne nagy szükség rá.

Hogyan írnak ma is egy floppy lemezen elférő, teljes értékű operációs rendszert grafikus felülettel és még pár játék is belefér?

Plusz még egy teljes értékű webböngésző, JavaScript motorostul. Azt se felejtsük el, hogy pl a Hanoi tornya játék JavaScriptben volt írva azon a bizonyos floppyn.

Szerkesztve: 2024. 03. 12., k – 08:47

A HUP "szakmai közösség" szakmai témában szakmait táncol ^ 🍿

trey @ gépház

Én csak egy autószerelő vagyok! Csak a 🍿-ért jöttem! Meg az elitet figyelni, aki szerint az a baj a HUP-pal, hogy nincs szakmai kontent és csak a flame megy! ^

https://gitlab.com/bztsrc/langcontest/-/tree/main/gelei

404 Page Not Found

trey @ gépház

Az enyemre azert nincs szukseg, mert en a "C a kiraly" tabort erositem, nem tudok nyelvet, amiben ez jobb lenne.

Ergo ez a kihivas nem nekem szol. :)

Ellenben aki a HWSW-nel arrol hazudozik, hogy megszunik a C, es felfefordit ennek a narrativanak megfeleloen forrasokat, annak se latom ott a kodjat.

XMI nezett utana olyan melysegben, hogy legyen eleg alapja helyreigazitast kerni:

https://hup.hu/comment/3033599#comment-3033599

https://hup.hu/comment/3033483#comment-3033483

(Bevallom, hirtelen ugy emlekeztem "trey" a cikk szerzoje, nem "hup" - hibasan)

egyreszt sehol nem lett leirva, h "megszunik" a c, ahogy te mondod, arrol van szo, h egyre nagyobb a nyomas, h helyettuk memoriabiztos nyelvet hasznaljanak. masreszt amikor akar cegek, akar kormanyzati szervek memoria biztonsagos nyelvekrol beszelnek, akkor hol nevesitik a c/c++ mint problemaforrast, hol nem. de ugye amikor memoria biztosnagos nyelvekrol beszelnek, ki tudod talalni mely nyelvek nem azok?

Nagyjabol onnan indultunk, hogy Egyesült Államok Nemzetbiztonsági Ügynöksége (NSA) kiadta anno ezt, ez alapja minden hivatkozasnak, es a 2023 kivervedelmi strategianak is. Azt hiszem ennel jobban nem lehet nevesiteni az emlitett nyelveket.
CSI_SOFTWARE_MEMORY_SAFETY.PDF (defense.gov)
NSA advises organizations to consider making a strategic shift from programming languages that provide little or no inherent memory protection, such as C/C++ and assembly, to a memory safe language when possible.

Nem én írtam, ugye. ;) Amúgy meg valóban az a bajom, hogy az újabb nyelvekkel elvész az alkotói szabadság, az ötletelés lehetősége. Ha ez így megy tovább, olyan mélységekbe jut a programozói szakma, mint az orvosi: protokollok vannak, mit hogyan kell kezelni, így aztán megölik a kreativitást, a beteget meg az Isten óvja attól, hogy ritka betegsége legyen, mert kötelezően félre fogják kezelni. :(

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem én írtam, ugye. ;)

Dehogynem, te jöttél a művészi szabadsággal :)

Amúgy meg valóban az a bajom, hogy az újabb nyelvekkel elvész az alkotói szabadság, az ötletelés lehetősége.

Egyébként meg a nehézség veszik el, mint ez a konkrét valami mutatja, pl a rustban is nyugodtan lehet alkotni, ha kell, csak amikor megszeged a józan ésszel az esetek nagy többségében betartandó normát, akkor le kell írni, hogy ezt teszed.

Ha ez így megy tovább, olyan mélységekbe jut a programozói szakma, mint az orvosi: protokollok vannak, mit hogyan kell kezelni,

Rengeteget elmond, ha szerinted egy szakmának az mélysége, hogy keretek, protokollok és best practicek vannak.

a beteget meg az Isten óvja attól, hogy ritka betegsége legyen, mert kötelezően félre fogják kezelni. :(

Egyrészt amíg nem voltak protokollok addig is félrekezelték ezeket, ha tippelnem kellene, akkor meg merném kockáztatni, hogy a protokollok növelik az esélyét, hogy egyáltalán feltűnjön, hogy itt valami nem stimmel. Abban viszont egészen biztos vagyok, hogy a nem ritka betegségben szenvedők (akik ugye a definíció szerint többen vannak) sokkal kiszámíthatóbban jutnak normális kezeléshez, mint ha ezek nem lennének.

így aztán megölik a kreativitást,

Dehogy ölik meg, magas szintű nyelveken, magas szintű problémákkal pontosan ugyanolyan kreatívan lehet foglalkozni, mint alacsony szinten alacsony szintű problémákkal. Csak szerinted -- mivel te azt szereted -- ezért az utóbbi érdekes kreatívkodás, az előbbi meg nem. Én pl azért nem szeretek odalent matatni, mert azt érzem, hogy az idő nagy része olyan problémák megoldásával megy el, amik irrelevánsak ahhoz képest, amit valójában meg akarok oldani.

---

Egyébként pedig: ez egy szakma, ha művészkedni akarsz, annak is van helye, kell menni demo scenre, lehet hobbizni meg minden. Kurva jó móka, de amikor épp szakma, akkor szakmázz. A doki se varjja matyóhímzéssel összes a sebet, mert egyébként az neki tetszik.

Nem ertem. Milyen kreativitasra vagysz mikor egy feladatra megoldast kell talalni az adott nyelvben, barmelyikben? Vagy azt mondjuk egyikben sincs vavyazt, hogy mindegyikben. C-ben, Python-ban, Go-ban, Scalaba-n is lehet szep es kreativ kodot irni. Bar en egy programnylevtol inkabb azt varom el, hogy az adott teruleten hatekony legyen. 

Az orvos se legyen kreativ, ne legyen piocazas, meg koponyalekeles, meg ne fessen novenyi anyagokkal a koldokom kore szines abrakat mikozben torokhangon enekel. Hanem fogja azt amit tanult meg amit tapasztalt es a tudasaval felvertezve a leheto leghatekonyabban vizsgaljon meg es diagnosztizaljon, majd talalja meg a gyogymodot. A vizvezetekszerelo se epitsen hullamvasutat a csovekbol, mert milyen kreativ, hanem vezesse el egyenesen a vizet oda ahova kell. Detto a villanyszerelo.

En sem habositom barokkos megoldasokkal amit az ugyfel ker. Amit en leteszek az esztalra az egy hatekony es gyors megoldas a problemajara. Ha azt akarja, hogy szines halacskak ugraljanak kozben elo valahonnan, akkor hivjon valaki mast.

A kérdésnél figyelembe kell venni a 2 kiindulási állapotát, azaz: 1 + 1
Jól látható a megoldás felé vezető út első lépése: az 1 az alapja ennek a problémának.
Az 1 pedig, mint köztudott 3 x (1/3), amelyet ha megvizsgálunk, rájövünk, hogy az 1/3 a kiindulási pont.
Vagyis 0,333333 + 0,333333 + 0,333333 = 0,9999999
Tehát 0,9999999 + 0,9999999 = 1,9999998
1,9999998 + 1,9999998 = 3,9999996
(Meg kell jegyeznünk, hogy a számítások közelítő értékűek.)
:)

Ha a specifikáció nem ilyen egyszerű, azonnal kinyílik a világ előtted. Mondjuk egy kommunikációs protokollt kell megvalósítani, meg egy másikat, meg méréseket, meg egy mérőrendszer vezérlését, az egész cucc csillió féle konfigurációját. Itt máris rajtad múlik, hogy blokkolósan, vagy kvázi multitaszkosan írod-e az egészet, a kommunikáció bufferelt lesz, vagy bevárod a választ rá, multitask megoldásnál hogyan oldod meg az interprocess kommunikációt, mert lehet minden egyes esetre egyedi globális változókon keresztül átadni paramétert, de lehet sokkal szebben, belső üzenetküldő infrastruktúrát kialakítani, az is a saját döntésed, az hogyan legyen megvalósítva, paraméterezve, a függvényeidet hogyan kelljen hívni, használni.

Az is a te döntésed, hogy pollingolva, IT-ből vagy DMA-val hozd el a kommunikációs modultól az adatokat, vagy add át neki. Tényleg csak a hardware és a fantázia korlátai léteznek.

Értem én, hogy 2+2 esetén nincs túl nagy mozgástér, de a gyakorlati problémák ennél picit szerteágazóbbak, és ezt te éppen úgy tudod. ;)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A valaszodban gyakran elofordulo fordulat "a rajtad mulik", ami akkor igaz ha hobbi projekten dolgozol sajat magadnak. Masreszrol a apeldad nagyon jol szemlelteti, hogy milyen tipusu problemakban csagy jaratos es azokban gondokodsz. 

A legtobb esetben visoznt a valo eletben ennel sokkal de sokkal jobban meg van kotve a kezed. Egyszeruen nem lehetsz kreativ. 

De ertettem amit irtal es a felvazolt esetben igazad is van.

Tőlem mit szeretnél látni? Nekem továbbra is a problémám ugyanaz. Ez nem bizonyítás. Tudom, hogy te sem érted, de neked van felmentésed ez alól.

Nem ismeretlen az alacsonyszintű programozás számomra, de nem szeretem. Rustot nem is ismerem, csak egy alap tutorialt csináltam meg benne. Ennyi.

Szerkesztve: 2024. 03. 12., k – 11:12

Ize ... nincs idom ilyenekre, te nyertel :D

Elegem lett a sok nagyszájúból

Ne etesd a trollokat!

Amugy minek fektetsz ennyi energiat ebbe?

Szerkesztve: 2024. 03. 12., k – 12:49

Hogy ne csak a levegőbe beszéljek, és tényleg korrekt összehasonlítás legyen, megcsináltam C nyelven és Rust-ban is. A Merge Request-et már ott a repo-ban.

Hogy izgalmas legyen, a C/C++ megoldás Visual Studio-val készült, PE formáutmú .exe az output-ja.

A háttérről: assembly-ben kb. 25 éve, még gyerekként programoztam értelmezhető mennyiséget, akkor kb. néhány száz óra nagyságrendű volt az idő, amit ebbe beletoltam. Meg volt egy könyvem, ami a 32 bites védett módú oprendszerekről szólt, ez hasznos volt annak kapcsán, hogy mi az az Interrupt Descriptor Table (ami egyébként koncepciójában nem sokat változott 64 bitre átállásnál). Ez most nagyon jól jött, hogy értsem miről is van szó, mit csinál az assembly nyelvű példa megoldás.

C nyelvvel már többet foglalkoztam, de igazán olyan sokat nem használtam, főleg az utóbbi 10 évben.

Rust-ot még soha nem használtam. Igazából erős kezdés volt így, hogy egyből egy rendszerprogramozási feladat :) Ez látszik is, hogy a nyelvet nem ismertem, sokkal inkább C jellegű a megoldás, kevésbé jól használja a Rust-os feature-öket. Ez jól látszik a már korábban elkészült Rust-os megoldáshoz hasonlítva. A legtöbb idő itt egyébként arra ment el, hogyan lehet bare metal bináris output-ot gyártani, hogyan lehet az outputhoz base address-t beállítani stb.

Amit mindkét megoldásban megcsináltam, hogy ne busy loop legyen a belépési pont végén a ciklus, hanem a HLT utasítást hajtja végre.

Összesen kb. tíz órát toltam bele. Napi szinten egyébként magasabb szintű nyelvekkel foglalkozok, C#, Java, JavaScript, Kubernetes, Cloud, DevOps témák.

Megjegyzés a peremfeltételekhez: az iretq hívást így kezelni, hogy a saját interrupt handlerből kell meghívni függvényként azt, ami majd valahogy kiléptet az egész interrupt handler-ből, ez szerintem szívás. Csak fragile megoldásokat találtam rá, de ahogy látom, mások is. A probléma gyökere, hogy egy magas szintű nyelvben, lényegében bármi ami nem assembly, nem igazán tudod megtippelni, hogy mekkora lesz a stack frame, amit el kell pusztítani, hogy az IRETQ gépi kódú utasítás a megfelelő stack pointernél fusson le. Itt kb. jósolni kell, hogy mi az a szám, amivel nem fagy le az egész gép. És ez lehet, hogy egy másik compiler verziónál már más lesz. Hogy itt tegyek javaslatot is, ezt szépen úgy lehet szoftver architektúra szempontból megcsinálni, hogy az interrupt handler egy rövid stub assembly-ben, akár a bootloader részeként, ami CALL utasítással meghívja a tényleges függvényt, ami a megoldás része, és a visszatérés után ez a stub lép ki IRETQ-val. Persze ekkor az eredeti megoldandó feladatnak egy jó része már kiesik, hiszen az IDT-t nem a megoldásban kell kitölteni, hanem a bootloader tölti ki, és a bootloader hív tovább a stub-ból a már normál módon megírt interrupt kezelő függvénybe.

az iretq hívást így kezelni, hogy a saját interrupt handlerből kell meghívni függvényként azt, ami majd valahogy kiléptet az egész interrupt handler-ből, ez szerintem szívás. Csak fragile megoldásokat találtam rá, de ahogy látom, mások is. A probléma gyökere, hogy egy magas szintű nyelvben, lényegében bármi ami nem assembly, nem igazán tudod megtippelni, hogy mekkora lesz a stack frame, amit el kell pusztítani, hogy az IRETQ gépi kódú utasítás a megfelelő stack pointernél fusson le. Itt kb. jósolni kell, hogy mi az a szám, amivel nem fagy le az egész gép. És ez lehet, hogy egy másik compiler verziónál már más lesz.

A válaszomhoz előrebocsátom, hogy én csináltam a Pascal verziót. A leírt jelenséghez nem kell másik compiler verzió, és én is belefutottam. Sokszor elég ha csak az optimalizációs beállítások változnak. Ez ugye befolyásol(hat)ja hogy hány változót tart a fordító a veremben és mennyit regiszterekben, amivel együtt az iretq() függvénynek átadandó szám is változik.

Erre - legalábbis Free Pascalban - több megoldás is van. Az első, hogy van két beépített compiler intrinsic, amivel ki lehet számolni a base pointer és az aktuális stack pointer közötti különbséget, amivel megkapod a localsize-t, és azt átadni az iretq függvénynek. Ami rendben volna, de szintén optimalizácíós célból a fordító szereti elhagyni a base pointert, és azt nem volt türelmem kipróbálni, hogy olyankor mi van, ezért csak beírtam én is egy számot, és kész.

A másik, hogy a Free Pascal alapvetően tud "interrupt" típusú függvényt fordítani, vagyis IRET-et generálni RET helyett a függvény végén. Emiatt nekem egy "interrupt acknowledge" függvény jobb lett volna. Az elegánsabb design is, mert akkor az interrupt acknowledge lehet platformfüggetlen (pl. másféle IRQ acknowledge, nem csak a legacy PIT van ám!), a fordító meg megoldja a többit. A másik amit te is leírsz, hogy ez így egy félmegoldás, ami nem elegánsan interfészelhető, mert félig nálad van az irányítás, félig meg a betöltőnél. És őszintén az sokkal jobb teszt lett volna ha már rendszerprogramozás, hogy a fordító tud-e önállóan interrupt stílusú függvényt generálni.

És ugyanitt disclaimer: Az x86_64 portja a Free Pascalnak nem tud (még) interrupt stílusú függvényt generálni. Igazából az egész embedded target félkész x86_64-en. Az infrastruktúra jelen van hozzá, i8086-on, i386-on megy, az x86_64 portból hiányzik a releváns kód, ami az interrupt stackframe-mel megküzdenie. Szóval nekem ebből a szempontból még jól is jött hogy iretq() van, de, rendszerprogramozási teszt szempontjából az a verzíó, hogy teljesen rád van bízva az interrupt handlerből való visszatérés, érdekesebb lett volna!

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

A Merge Request-et már ott a repo-ban.

Köszönöm, máris hozzáadom!

A legtöbb idő itt egyébként arra ment el, hogyan lehet bare metal bináris output-ot gyártani,

Erre elvileg nincs szükség, a betöltő pont azért van. Bármilyen szabályos ELF vagy PE/COFF betölthető velük, nem kell alacsony szintű raw binary fájlokkal vacakolni, meg futásidőben valós módban betölteni a fennmaradó részt.

Megjegyzés a peremfeltételekhez: az iretq hívást így kezelni, hogy a saját interrupt handlerből kell meghívni függvényként azt, ami majd valahogy kiléptet az egész interrupt handler-ből, ez szerintem szívás.

Tessék az AMD és Intel mérnököknél panaszkodni, ne nálam. Így működik a CPU, ezt nem tudod megkerülni. Még Assembly-ben is külön speciális utasítás van erre (aminek a neve történetesen "iretq").

nem igazán tudod megtippelni, hogy mekkora lesz a stack frame

Dehogyisnem! Pontosan tudod, hogy a stackframe egyetlen változót helyez a verembe (a korábbi stackframe tetejét), és ez nyelv valamint fordító független, illetve a függvényhívás CALL utasítás mégegyet, de ez megint nyelv és fordító független.

Itt kb. jósolni kell, hogy mi az a szám, amivel nem fagy le az egész gép. És ez lehet, hogy egy másik compiler verziónál már más lesz.

Egy C program ezen a CPU specifikus működésen túl nem is nyúl a veremhez (amennyiben a függvény nem tartalmaz lokális változót).

Pont ez volt a verseny egyik célja, hogy az ilyenekre, amire itt panaszkodsz, rávilágítson: a Rust nem egy jövőbiztos megoldás, a C-vel ellentétben nincs semmi garancia arra, hogy 5 év múlva is működőképes programot fog fordítani! Simán lehet, hogy addig vagy 10x átírják az ABI-ját, ami úgy fogja eltörni a kódodat, hogy közben nem változik a forrásod egy bitet se!

Bocs, de amit a C fordító "nem nyúl a veremhez" eszmefuttatásról írsz, az egyáltalán nincs így és 100% fordító specifikus. És amint írtam, még optimalizációs beállítástól is függhet (pl. generál-e a fordító frame pointert az rbp-be, ezt eltárolja-e a verembe vagy sem). Erről vajmi keveset ír az ABI... Ez egy olyan dolog amire _semmi_ garancia nincs. Sem C-ben, sem semmiylen nyelven.

Most kipróbáltam, GCC 12.2.0, x86_64 Debian bookworm, természetesen -O3-mal egy üres függvény kizárólag egy "ret"-re fordul, míg -O0-val beletolja a frame pointert is a stackbe. Szóval ha erre akarod építeni az elméleted hogy a Rust miért nem "jövőbiztos" akkor ez masszívan mellément.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Bocs, de amit a C fordító "nem nyúl a veremhez" eszmefuttatásról írsz, az egyáltalán nincs így és 100% fordító specifikus. És amint írtam, még optimalizációs beállítástól is függhet

Nem. A stackframe maga független. Az optimalizációtól csak az függ, hogy teljes egészében kimarad-e vagy sem, az nem, hogy hogyan működik.

Szóval ha erre akarod építeni az elméleted hogy a Rust miért nem "jövőbiztos" akkor ez masszívan mellément.

Nagyon nem! Fogadjuk, hogy 10 év múlva is épp ugyanúgy be fogja tenni a stackframe-t bármelyik C fordító -O0 esetén, és épp ugyanúgy csakis a korábbi stackframe tetejét fogja csak a verembe tenni, semmi mást! Ez már a DOS-os fordítóknál is így működött, és gcc 2.0 (a legelső gcc verzió, amit használtam) óta egész biztos így van, Clang alatt is így van, és az is biztos, hogy így is fog maradni. Mind a gcc, mind a Clang esetén különösen odafigyelnek a backward kompatíbilitásra (a -O3 persze nagy valószínűséggel generálhat mást, de az -O0 nem fog változni, ebben biztos vagyok).

Az hogy a stackframe miért nem változik, annak sokkal inkább ABi és hardware-es okai vannak, semmint fordító okai, ezért volt már így DOS-on és GCC2.0-n is... De a localsize attól még megváltozik az optimalizációtól, ergó át kell írni azt a rohadt konstanst.

Másrészt ha jól értem akkor a vélemény és érvrendszer átment abból hogy a "C garantálja a kompatibilitást" abba hogy a "C garantálja a kompatibilitást -O0 esetén". Ami vicces lenne, ha nem lenne legalább annyira szomorú...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Az hogy a stackframe miért nem változik, annak sokkal inkább ABi és hardware-es okai vannak, semmint fordító okai, ezért volt már így DOS-on és GCC2.0-n is...

Pontosan, nem fordító specifikus.

De a localsize attól még megváltozik az optimalizációtól, ergó át kell írni azt a rohadt konstanst.

Természetesen. De nincs más mód. Ha tudsz egy bármilyen más megoldást erre, mint a localsize változó átadása, csak szólj és lecserélem.

Másrészt ha jól értem akkor a vélemény és érvrendszer átment abból hogy a "C garantálja a kompatibilitást" abba hogy a "C garantálja a kompatibilitást -O0 esetén".

Annyiban jogos, hogy valóban nem írtam explicit ki, mert magától értetődőnek vettem, hogy a fordítók optimalizálójai folyamatosan fejlődnek és változnak, és hogy a megoldásom -O0-át használ. Valóban explicit ki kellett volna már írnom a legelején a félreértések elkerülése végett.

De nincs más mód. Ha tudsz egy bármilyen más megoldást erre, mint a localsize változó átadása, csak szólj és lecserélem.

Valószínűleg a "helyes" megoldáshoz nem fogod megúszni, hogy az interrupt handlered egy assembly függvénybe lépjen be először. Hiszen a mostani megoldás kb. "véletlenül",  a megszakításkezelő egyszerűsége és a főprogram gyakorlatilag teljes hiánya miatt működik (így a főprogram nem kerül regiszter-konfliktusba a megszakításkezelővel). Az interruptkezelőnek ugyanis nem csak az ABI által deklarált, hanem az összes regisztert le kell(ene) mentenie, beleértve az ABI által scratch regiszterként definiáltakat, az FPU-t és a multimédia (SIMD) regisztereket is.

Mint mondtam, Free Pascalban lehet "interrupt"-ként deklarálni egy függvényt, akkor a fordító magától tudja, hogy az összes regisztert le kell mentenie és visszaállítania, ill. hogy iretq-t kell fordítania a függvény végén. Ha ez nincs, mert az adott nyelv kevésbé alkalmas rendszerprogramozásra mint egy Pascal (trollface), akkor nincs más megoldás mint az assembly stub-ból callback, amit már szintén mondtak itt páran.

Ezt az egészet egyébként részletezi ez a cikk. Amit - ó az irónia - Rust-hoz írtak.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Nagyon nem! Fogadjuk, hogy 10 év múlva is épp ugyanúgy be fogja tenni a stackframe-t bármelyik C fordító

Ez szerintem elég rossz megközelítése a kérdésnek, ezt semmi sem garantálja. Ez a törékeny megoldások mintaképe. A fordítónál a backward compatibility nem erről szól, hogy ilyen jellegű garanciákat adna. Ezzel inkább csak magadnak és másoknak adsz munkát, amikor később egy ilyet javítani kell.

Célszerűbb előremutatóbban gondolkozni, és olyan megoldásokat és program struktúrákat keresni, amik definíció szerint jól fognak működni, később is, garantáltan.

Célszerűbb előremutatóbban gondolkozni, és olyan megoldásokat és program struktúrákat keresni, amik definíció szerint jól fognak működni, később is, garantáltan.

Nyilván, de akkor a Rust labdába se rúghatott volna a verseny során, mert mindenképp Assembly-ben kellett volna megírni a necces részt.

Erre elvileg nincs szükség, a betöltő pont azért van. 

Itt arra gondolok, hogyan tudom azt elérni, hogy a Rust által generált output az ne támaszkodjon arra, hogy van oprendszer, ill. van C runtime. Van ehhez opció, csak nyilvánvalóan ez az erősen haladó rész. Ahogy mondtam, ez az első Rust programom. Szóval ez inkább a saját szívásom volt :)

Tessék az AMD és Intel mérnököknél panaszkodni, ne nálam. Így működik a CPU, ezt nem tudod megkerülni. Még Assembly-ben is külön speciális utasítás van erre (aminek a neve történetesen "iretq").

Ezzel én teljes mértékben tisztában vagyok. És semmi hiba nincs a CPU utasításkészletében. Itt csakis abban van a hiba, hogy te hogyan tervezted meg, hogy a megoldás futása során majd meghívódjon az IRETQ utasítás. Arra gondolok, hogy ahelyett, hogy

Magas szintű nyelven írt handler kezdete:
  Implementációs lépések...
  Továbbhívás a bootloader iretq függvényébe
    Bootloader iretq függvény kezdete:
      Magic a stack pointerrel, mert nem tudod, hogy a hívó magas szintű implementáció mekkora stack frame-et csinált
      OUT instruction
      IRETQ instruction
    Bootloader iretq függvény vége
Handler vége

sokkal értelmesebb így csinálni:

Handler kezdete:
  Továbbhívás a magas szintű nyelvi implementációba
    Magas szintű nyelvi implementáció belépési pontja:
      ...
    Magas szintű nyelvi implementáció vége
  OUT instruction
  IRETQ instruction
Handler vége

nem igazán tudod megtippelni, hogy mekkora lesz a stack frame

Egy C program ezen a CPU specifikus működésen túl nem is nyúl a veremhez (amennyiben a függvény nem tartalmaz lokális változót).

Ez tippre nem így van, szerintem lehet olyan bonyolult kifejezéseket csinálni, ahol lokális változó nélkül is muszáj a stack-hez nyúlnia a compilernek. Másik szempont: ha csapatban dolgozol? És bárki hozzáad később egy lokális változót a függvényhez? Akkor mindenki vakarhatja a fejét, hogy mitől fagy le az egész, mert van valahol benne egy magic constant, aminek elmászott az értéke.

És ez teljesen igaz C-re és Rust-ra is. Ez a fajta megközelítés nyelvfüggetelenül szívás. Ahogy mások is írták, akár compiler optimalizációs szinttől is függ. Pl. a Microsoft compiler a CALL helyett JMP hívással megy tovább a bootloader-ed függvényébe, mivel látja, hogy ez a függvény utolsó sora. Úgy itt ezért kellett pl. negatív szám ahhoz, hogy mekkora a stack frame.

Azt akartam ezzel mondani, hogy ez egy értelmesebb méretű rendszernél átgondolandó. A jelen példaprogramnál persze tökmindegy, mondhatni a kihívás része :)

Pl. a Microsoft compiler a CALL helyett JMP hívással megy tovább a bootloader-ed függvényébe, mivel látja, hogy ez a függvény utolsó sora. Úgy itt ezért kellett pl. negatív szám ahhoz, hogy mekkora a stack frame.

Ezt amúgy úgy hívják hogy tail-call optimization és/vagy tail call elimination és szabvány optimalizációs gyakorlat. Wiki cikk is van róla. Szerintem a GCC is csinál ilyet bizonyos esetekben. De igen, fordítófüggő hogy hányszor és hogyan és milyen helyzetekben használja.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Bocs, a megoldśaod nem néztem még, csak a hozzászólásra reagáltam. Az mindenesetre beszédes, hogy ha jól értem a kihívást az eredeti kiírótól függetlenül megoldók, 3 különböző nyelv és 4 különböző fordótó ellenére is egyetértünk abban, hogy ez az interfész így nagyon nem kerek és inkább a "hogyan ne" példája, semmint annak hogy miért Rust-ban ne. :)

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

sokkal értelmesebb így csinálni:

Persze, na de ekkor Assembly-ben kell írnod wrapper függvényeket, Assembly-ből kell az IDT-t betölteni, és Assembly függvények címét tartalmazná az IDT. Magyarán az égadta világon semmit sem tesztelnél a nyelvből, mert gyakorlatilag minden Assembly-ben lenne. Nyilván megoldható a feladat, ha minden Assembly-ben van és nem az adott nyelven.

Ez tippre nem így van, szerintem lehet olyan bonyolult kifejezéseket csinálni, ahol lokális változó nélkül is muszáj a stack-hez nyúlnia a compilernek.

És megintcsak persze, de elfelejted, hogy a kifejezés végére muszáj visszaállítani a stack pointert a kifejezés előttire, különben nem működhetne a program. Magyarán olyan, mintha nem is változott volna a stack.

És megintcsak persze, de elfelejted, hogy a kifejezés végére muszáj visszaállítani a stack pointert a kifejezés előttire, különben nem működhetne a program. Magyarán olyan, mintha nem is változott volna a stack.

Ez komoly tévedés. Kétségeim vannak a hozzáértéseddel kapcsolatban. A stack pointer a függvény végén áll vissza arra amire kell. Nem pedig a kifejezés végén. Hogy függvény közben hogyan mozog akár a 14. és 16. sor között, az teljesen a fordítóra van bízva.

Nem tudom, mire gondolsz. Csak arra tudok gondolni, hogy úgy érted, hogy van olyan optimalizáció (vagyis inkább az optimalizáció teljes hiánya), amikor minden olyan ponton, ami egy kifejezés végének felel meg a forráskódban, visszaáll egy biztos értékre. Ha teljesen precízen akarod, akkor valóban úgy kellett volna írnom, hogy a kifejezés végén nem kell visszaállnia, de visszaállhat. Viszont a lényeg továbbra is az, hogy a függvény végén van az a pont, amikor vissza kell állnia.

De amúgy van ennek jelentősége? Ha jól definiált működésű program struktúrákban gondolkozol, akkor ezek a részletek pont hogy nem számítanak. Csak arra próbálunk többen is rávilágítani, hogy a törékeny megoldás sok ponton törhet el. Egyszerűbb az a program struktúra, ahol nem számít, hogy pontosan mi történik.

Csak arra próbálunk többen is rávilágítani, hogy a törékeny megoldás sok ponton törhet el.

Csak arra próbálok rávilágítani, hogy alaposan összetéveszted a nyelv kifejezőerejét tesztelni hivatott, szándékosan pofonegyszerű célfeladatot egy bármilyen production ready programstruktúrával.
Ennyi erővel azzal is érvelhetnél, hogy soha senki ne vegyen Trabantot, mert törékeny és nem jó bele a V8-as motor!

Az, hogy az IDT-t a nyelvből kell beállítani ennél a feladatnál, nem azért van, mert így szokás, hanem mert konkrétan két dolgot is tud tesztelni ezáltal: átadható-e magasszintű tömb alacsonyszintű utasításnak, és hogy magaszintű függvény címén végezhető-e logikai művelet, mert bizony ezek a fránya hardver mérnökök sokszor ilyen elvárásokat támasztanak a rendszerprogramok felé, és nemcsak az IDT-ben, de például az IDT-ben is, így egy nyelv ellenőrzésre kiváló. Érted már?

Az, hogy az IDT-t a nyelvből kell beállítani ennél a feladatnál, nem azért van, mert így szokás, hanem mert konkrétan két dolgot is tud tesztelni ezáltal: átadható-e magasszintű tömb alacsonyszintű utasításnak, és hogy magaszintű függvény címén végezhető-e logikai művelet

Szerintem te nem érted, hogy mi a problémám, és másoknak is, aki vette a fáradságot és adott be megoldást. Nem az a gond, hogy mit lehet megoldani Rust-ban (az már felmerülhet, hogy mit célszerű, de most ugye pont arról volt szó, hogyha összeszorítjuk a szánkat, akkor akár ezt a kihívást is meg lehet benne oldani.) Az élő példák mutatják, hogy az IDT felprogramozást is meg lehet írni Rust-ban.

Hanem az a probléma, hogy egy olyan interfészt definiáltál a feladatkiírásban, ami ahogyan összeköti a bootloader-ed meglévő kódját a beadandó megoldással, az törékeny. Most fogalmazzak úgy, hogyha a bootloader ezen része is Rust-ban lenne írva, akkor nem lenne ez a gond :D. De nem így akarok fogalmazni, mert nem akarom megemelni a vérnyomásodat. Úgy fogalmaznék, hogy célszerű olyan interfészt csinálni, ahol bármilyen nyelven van a bootloader, és bármilyen nyelven a megoldás, köztük legyen stabil a bináris interfész.

Hanem az a probléma, hogy egy olyan interfészt definiáltál a feladatkiírásban, ami ahogyan összeköti a bootloader-ed meglévő kódját a beadandó megoldással, az törékeny.

Na akkor mégegyszer, mutass egy bármilyen más megoldást rá és lecserélem. Az egyetlen kitétel, hogy nem lehet Assembly-ben az egész.

Tökéletesen tisztában vagyok vele, hogy törékeny, ezt már többször jeleztem is, hogy a CLang és fastcall ABI esetén is van vele probléma.

Úgy fogalmaznék, hogy célszerű olyan interfészt csinálni, ahol bármilyen nyelven van a bootloader, és bármilyen nyelven a megoldás, köztük legyen stabil a bináris interfész.

Naná, de az a betöltő nem lenne képes tesztelni a nyelvet. Mit nem lehet érteni azon, hogy ez nem egy célszerű betöltő, hanem direkt specifikusan a nyelvek tesztelésére készült, szándékosan csakis ehhez a feladathoz?

Megpróbálok vázolni egy megoldást. Ehhez először lássuk mi a probléma: eltérő oldalakon vannak definiálva az IDT felprogramozási pont és belépési pont (ezek a megoldandó feladatban, továbbiakban solution), és a kilépési pont (ez a bootloaderben, továbbiakban bootloader :)). Továbbá meg akarjuk tartani azt, hogy az IDT felprogramozás az továbbra is a megoldandó feladatban maradjon, hogy továbbra is téma maradhasson, hogy lehet-e tömböt bitmintával feltölteni Rust-ból.

Ezt át kell alakítani (tőlem mondhatjuk azt is, hogy refaktorálni), hogy valahogy úgy nézzen ki, hogy az IDT felprogramozás a megoldandó feladat része maradjon, az interrupt handler belépési pont és kilépési pont a bootloaderben van, viszont a tényleges timer kezelés már újra a megoldandó feladatban. Így nem keveredik az, hogy a közvetlen IRQ belépés és IRQ kilépés különböző rétegekben van.

Ez úgy működhet, hogy a bootloader úgy hívja meg az ELF vagy PE bináris belépési pontját, hogy átad egy második paramétert is, egy függvény címét, ami az interrupt handler közvetlen belépési pontjának címe, és a bootloaderben van implementálva (legyen ennek a neve bootloader_timer_handler). A megoldandó feladat úgy programozza az IDT-t, hogy ezt a második paraméterként megkapott bootloader_timer_handler adja át a timer interrupt címéhez az IDT-ben.

A bootloader interfészből el kell dobni az iretq függvényt, helyette fel kell venni egy olyan új függvényt, hogy set_solution_handler_address. Ezt az interruptok bekapcsolása előtt kell még meghívni a megoldandó feladatban. Egy paramétert vár, a megoldandó feladatban magas szintű nyelven megírt függvény címét. A bootloader ennek meghívásakor elmenti a megkapott függvény címét a solution_handler_address változóba. A bootloader_timer_handler pedig abból áll a bootloaderben implementálva, hogy CALL utasítással behív a solution_handler_address változóban tárolt címre, utána meg megcsinálja az OUT és IRETQ utasításokat. Ezzel az a struktúra fog kialakulni, amiről már az elején itt írtam: https://hup.hu/comment/3037581#comment-3037581

Javaslom, hogy ezeket a változásokat úgy csináld meg, hogy külön branchen, vagy ilyesmi, hogy a már beadott feladatok még működjenek.

átad egy második paramétert is, egy függvény címét, ami az interrupt handler közvetlen belépési pontjának címe, és a bootloaderben van implementálva

Hát ez az, ha ez a betöltőben lenne Assembly-ben implementálva, akkor egyáltalán nem lenne alkalmas a nyelv tesztelésére.

Mégegyszer, ha nem kifejezetten azt akarnánk tesztelni, hogy csakis a nyelvben rendelkezésre álló eszközökkel, magas szintű függvényekkel, Assembly nélkül megoldható-e a megszakításkezelés (ami egy tipikus példája a nyakatekert rendszerprogramozásnak, tömbátadással, függvénycím bitshifteléssel stb.), akkor nyilván én is Assembly wrappert használnék. Sőt, mi több, tuti, hogy nem megírnám, hanem Assembly makrókkal generáltatnám ki, az ISR-eket éppúgy, mint az IDT tartalmát. Interfész helyett meg egyetlen inline Assembly-vel töltetném be az IDT címét. De hát pont az a cél itt, hogy csakis a nyelv natív eszközkészletét lehessen használni, mivel arra vagyunk kíváncsiak, hogy azzal megoldható-e.

Figyeld meg, az interfész direkt csak CPU utasításokat burkol körbe, a lehető legalacsonyabb szintű. Az első draft-ban az "iretq" tényleg csak egy "iretq" utasítás volt, és volt benne "inb" meg "outb" is. Aztán úgy döntöttem, hogy még a megszakításvezérlőt se kelljen nyugtázni, mert az már nem nyelvi ismereteket, hanem meghajtóprogramozási ismereteket igényel, azért kikerült az "inb" / "outb" az interfészből, a nyugtázás meg bekerült az "iretq"-ba.

Hát, szerintem ez a gondolatkísérlet ott sántít, hogy azzal, hogy ragaszkodsz a kiindulási struktúrához, nem azt teszteled valójába, amit akartál, hogy vajon a Rust jobb/rosszabb-e mint a C. Mert mint látszik, mindegyikben sikerült megoldást írni. És egyébként mindegyik nagyon hasonló felépétésében, a Pascal-os is. És mindegyik törékeny, igen a C is.

Aminek oka, hogy a kiindulási peremfeltételeid mentén, ha ezekhez továbbra is ragaszkodsz, mindegyik megoldás csak törékeny lehet. Kivéve az assembly, de ugye most valamiért ehhez ragaszkodsz, hogy assembly ne lehessen a megoldás része. Ha van benne unsafe, akkor miért ne lehetne kb. 3 sor assembly is? És ismétlem, ez C-nél is ugyanúgy kell ahhoz, hogy jól struktúrált legyen a megoldás. És akkor most ez a néhány sor assembly vagy a bootloaderbe kerül egészében, vagy a megoldandó feladatba egészében. Másképp nem fog menni.

Még lehetne esetleg azzal játszani, hogy semmi sincs a bootloaderben, minden a megoldandó feladatban van, belépés és kilépés, és nem assembly-ben, de akkor a nyelvnek explicit támogatni kell azt, hogy egy függvény nem normál függvény, hanem interrupt handler.

Van ilyen kezdeményezés a Rust-nál, de még nincs kész: https://github.com/rust-lang/rust/issues/40180

És itt a C szintén elvérzik (hoppá, erre számítottál?): https://stackoverflow.com/questions/21336730/can-interrupts-be-handled-…

nem azt teszteled valójába, amit akartál, hogy vajon a Rust jobb/rosszabb-e mint a C

Dehogyisnem, pontosan azt. Olvasd csak el a kiírást, a cél mindig is az volt, hogy kiderüljön, ha meg lehet oldani, akkor mennyi hekkelés és speciális kulcszó árán. C alatt ehhez egyetlen speciális kulcsszó sem kell, simán működik mezei függvényként is. Quod Errat Demonstrandum.

Még lehetne esetleg azzal játszani, hogy semmi sincs a bootloaderben, minden a megoldandó feladatban van, belépés és kilépés, és nem assembly-ben

Nem, nem lehetne. Sosem fogsz pl. lidt vagy sti utasítást generáltatni semmilyen magas szintű nyelvből. Ehhez minimum inline Assembly kell.

És itt a C szintén elvérzik (hoppá, erre számítottál?)

LOL! Most komolyan utolsó szalmaszálként azt próbálnád tagadni, amire több működő PoC is van...? Legalább 2 ember legalább 4 különböző programban simán megoldotta...

C alatt ehhez egyetlen speciális kulcsszó sem kell, simán működik mezei függvényként is. 

Működik, de törékeny. Tehát a "simán működik" nem helytálló. Ezt mások is részletezték, hogy különböző C fordító opciókkal hogy változik a stack frame mérete.

Még lehetne esetleg azzal játszani, hogy semmi sincs a bootloaderben, minden a megoldandó feladatban van, belépés és kilépés, és nem assembly-ben

Nem, nem lehetne. Sosem fogsz pl. lidt vagy sti utasítást generáltatni semmilyen magas szintű nyelvből. Ehhez minimum inline Assembly kell.

Itt nem az LIDT utasításra gondoltam, a "minden"-nel az interrupt handler belépésére ÉS kilépésére utaltam, és ez szerepel a mondatomban is. Jelenleg a belépés a magas szintű nyelvben van, a kilépés a boot loaderedben, és mondjuk ki, ez a szálban részletezett probléma gyökere.

És ahogy látható, ez másnak is szemet szúrt, aki szintén megoldotta. Jó tanács: ha mindenki szembe megy az autópályán, érdemes elgondolkozni, hogy ki tévedt el...

LOL! Most komolyan utolsó szalmaszálként azt próbálnád tagadni, amire több működő PoC is van...?

Ez nem utolsó szalmaszál, valamit félreértesz. Ez arra utalt, hogy van-e nyelvi elem arra, hogy a fordító IRETQ-t generáljon. És jelenleg se a szabvány Rust-ban, se a szabvány C-ben nincs.

Lehet, hogy elkeveredtél a thread-ek és hozzászólók közt, de én oldottam meg C-ben és Rust-ban is, egyszerre. Szerintem komoly szövegértési problémáid vannak, és fel sem fogod, hogy mit próbálok magyarázni itt sok hozzászóláson keresztül, hogy igen, vannak megoldások a feladatodra, több nyelven is. De mindegyik törékeny, és hogy miért, azért, mert olyan interfészt találtál ki, ami magas szintű nyelven csak törékeny lehet, és ragaszkodsz ahhoz, hogy ne legyen assembly a megoldásban.

Tovább nem fogom ezt részletezni, mert úgy érzem, hogy felesleges, mert egyszerűen fel sem fogod igazán, hogy miről próbálok itt beszélni, mi a probléma. Sajnálom.

Jelenleg a belépés a magas szintű nyelvben van, a kilépés a boot loaderedben, és mondjuk ki, ez a szálban részletezett probléma gyökere.

Ez arra utalt, hogy van-e nyelvi elem arra, hogy a fordító IRETQ-t generáljon. És jelenleg se a szabvány Rust-ban, se a szabvány C-ben nincs.

Itt most saját magad ismerted be, hogy a kilépés nem is lenne sehogy másként megoldható (az inline Assembly ugye nem megengedett).

Nem nekem vannak szövegértési problémáim, hanem Te keveredtél önellentmondásba.

olyan interfészt találtál ki, ami magas szintű nyelven csak törékeny lehet, és ragaszkodsz ahhoz, hogy ne legyen assembly a megoldásban.

A lehető legegyszerűbb interfészt alkottam meg, aminél natív függvényben van a megszakításkezelő belépési pontja, és igen, ragaszkodom hozzá, hogy ne Assembly-ben legyen, mert akkor az - ki hitte volna - Assembly-ben lenne és nem az adott nyelven.

Itt most saját magad ismerted be, hogy a kilépés nem is lenne sehogy másként megoldható (az inline Assembly ugye nem megengedett).

Így van a kilépés nem oldható meg, assembly kell. De továbbra sem érted, hogy akkor jól strukturált és nem törékeny a program, ha a kilépés és a belépés ugyanabban a rétegben van (vagy a bootloaderben, vagy megoldásban). Tehát a belépésnek is assembly-ben kéne lennie, hogy ne legyen törékeny.

De lehet, hogy nem szövegértési problémák vannak, hanem a rövidtávú memórával vannak gondok. Milyen érdekes, hogy pont ma részleteztem neked, hogyan oldható ez meg normálisan:

https://hup.hu/comment/3037581#comment-3037581

https://hup.hu/comment/3037646#comment-3037646

 

A lehető legegyszerűbb interfészt alkottam meg, aminél natív függvényben van a megszakításkezelő belépési pontja, és igen, ragaszkodom hozzá, hogy ne Assembly-ben legyen, mert akkor az - ki hitte volna - Assembly-ben lenne és nem az adott nyelven.

Oké, ragaszkodj hozzá, de ezzel nem a C/Rust között teszel különbséget, mert ismét, sokadszor, mindkettőben pont ugyanolyan törékeny megoldást lehet csak gyártani. Amivel nincs gond egy ilyen kihívásnál, ha odatesszük mellé, hogy igen, itt a megoldás, de törékeny, mert ilyen a kiírás.

Így van a kilépés nem oldható meg, assembly kell.

És te mégis felróttad.

pont ma részleteztem neked, hogyan oldható ez meg normálisan:

Világosan megmondtam, hogy miért rossz. Ha nem érted, az nem az én bajom, de a megoldásod egyszerűen nem alkalmas arra a feladatra, amire ez a verseny hivatott. A gyorsfutókat sem centivel méred, hanem stopperrel.

ezzel nem a C/Rust között teszel különbséget

Még véletlenül sem azért van az egységes interfész, hogy bármiféle különbséget tegyen, pont ellenkezőleg.

törékeny megoldást lehet csak gyártani

Miért nem vagy képes megérteni, hogy a verseny célja a nyelv kifejezőerejének és az ehhez szükséges gányolások mennyiségének felmérése és nem pedig egy atomstabil operációs kernel írása?

Rohadtul senkit nem érdekel, hogy törkény-e a kizárólag ehhez az egy feladathoz megalkotott egyszeri interfész, mert kurvára senki sem fogja sehol máshol, de pláne nem egy production rendszerben soha felhasználni. Egyetlen egy célja van, és arra alkalmas, pont.

Azért részedről sem ártana egy bocsánatkérés.
Olyant követelsz, ami sosem volt cél ennél a versenynél, kb. mintha azt várnád el a magasugróktól, hogy egyben tökéletes balett-táncosok is legyenek. Ne csodáld, ha elsőre felhúztam magam. És igen, gyorsan korrigáltam, mert személyeskedés nélkül is igazam van.

Nem volt sértő szándékom, én egész eddig csak azt próbáltam átadni (és nem követeltem, igyekeztem úgy fogalmazni, hogy javaslat legyen), és szerintem az itteni szokásokhoz képest meglehetősen elég konstruktívan: https://hup.hu/comment/3037646#comment-3037646 hogy hogyan lehet azt megoldani, hogy ne legyen szívás az interrupt-ból való kiszállás.

Beláthatod, hogy ez egy fájó pont, és emiatt a beadott megoldások "csúnyák" és "törékenyek", ezt más is jelezte, hogy bántja a szemét. És ilyenkor felmerül, hogy lehetett-e volna jobban megcsinálni a kiírást.

Lehet, hogy nem adtam át elég jól érthetően, de ez egy olyan átalakítás, hogy a timer kezelő továbbra is Rust/C, ahol az eddigi beadott programok lényegében annyit változnak csak, hogy a timer kezelő utolsó sora nem a bootloader felé az iretq hívás, hanem csak simán a függvény vége (normál visszatérés egy normál függvényből). De maga függvény, a counter növelés, képernyőre kiírás tökéletesen ugyanúgy néz ki, Rust-ban vagy C-ben van implementálva, pont úgy mint a már meglévő megoldásokban, nem kell emiatt assembly sehol a megoldásban, és nincs a törékeny alloc_size magic konstans. Tehát szinte ugyanúgy néz ki minden, pontosan ugyanúgy teszteled a nyelvek közti különbségeket és hasonlóságokat.

szerintem az itteni szokásokhoz képest meglehetősen elég konstruktívan

Szerintem is. Ezért is döntöttem úgy, hogy módosítom a korábbi posztom.

programok lényegében annyit változnak csak, hogy a timer kezelő utolsó sora nem a bootloader felé az iretq hívás, hanem csak simán a függvény vége (normál visszatérés egy normál függvényből)

Pontosan. És mivel ez egy normál visszatérés egy normál függvényből, pont ezért alkalmatlan annak tesztelésére, amiről itt szó van. Azt se felejtsük el, hogy ilyenkor a megszakításkezelő belépési pontja is Assembly, és nem pedig natív függvény.

De maga függvény, a counter növelés, képernyőre kiírás tökéletesen ugyanúgy néz ki

Ez így önmagában alkalmatlan annak eldöntésére, hogy egy nyelv használható-e rendszerfejlesztésre, ami az egyik kiemelt szempont.

Tehát szinte ugyanúgy néz ki minden, pontosan ugyanúgy teszteled a nyelvek közti különbségeket és hasonlóságokat.

Nem. Ezáltal pont azt iktatnád ki a tesztből, a lényege.

A számláló maga nem érdekes, az csak azért van, hogy ne kelljen debugger ahhoz, hogy lássuk, működik-e. A lényeg az az, hogy alacsony szintről hívódjon egy magas szintű, adott nyelven íródott funkció, a lehető legkevesebb hekkeléssel.

Nem. Ezáltal pont azt iktatnád ki a tesztből, a lényege.

Hát nem, mert a gyakorlatban született megoldások azt mutatják, hogy az interrupt-ba belépés pofonegyszerű minden eddigi megoldás nyelvén, a kilépés meg "bizonytalan" minden eddig nyelven. Tehát akkor itt mégis mit döntünk el a rendszerprogramozhatóság lehetőségéről az egyes nyelvek között? Szerintem semmit, mert az derül ki, hogyha megbízhatóan akarsz interrupt kezelést programozni (rendszerprogramozni), akkor muszáj egy assembly stub a belépésre ÉS kilépésre is. És ez igaz C-re, Rust-ra, Pascal-ra is.

Tehát továbbra is igaznak tartom, hogy a javasolt átalakítással nem veszted el a rendszerprogramozhatóság eldöntését a nyelvek között, de egy korrektebb keretet adsz az egésznek.

Azt már csak halkan jegyzem meg, hogy az inline assembly a Rust nyelv specifikációjának része, a C-nek viszont nem. Tehát az lenne a helyes értelmezés, hogy Rust pályaműben használhatjuk, C-ben viszont nem. Lassan ott tartunk, hogy kiderül, hogy bzt saját meghatározása szerint a Rust alkalmas rendszerprogramozásra, de a C nem :-)

Azért azt pointer mentesnek nevezni, hogy a videó memória tömbödet a linkerrel fix címre rakatod, az elég furcsa érvelés. Valóban kevesebb a * karakter a C kódodban, mert így nem pointerrel éred el a fix címet, de attól még te is pontosan tudod, hogy ez tökéletesen ugyanaz, mint egy pointer egy fix címre, csak a linker eszközeivel megoldva, és tökéletesen ugyanaz, mint a Rust-ban az unsafe blokkban a pointer egy fix címre.

Azért itt felmerül az a kérdés, hogy a postás a Kossuth utca 10 címre érkező levelet vajon fix címre hordja ki vagy pointerrel? És csak a linker eszközeivel megoldva a pozícióját változtatja-e a Kossuth utca 10? Vajon postás bátyánk melyik esetben rohan túl - unsafe módon - az adott címen? :-D

Ha ez ellen akarsz védekezni, akkor kell valami API, amivel eléred a képernyőt. Amennyiben közvetlenül írsz a memóriába, memóriába ágyazott perifériára, úgy mindig követhetsz el hibát. Azt nem értem, hogy ez miért baj. Például while (true);, aztán puff, wathcdog reset. Szóval ahhoz nem kell sokat tenni, hogy valamit elrontsunk, de lehet a fenti példában szándékos is annak a wd resetnek a triggerelése. Akkor ez most bug vagy feature? Attól függ, hol írom le az adott kódot és mi vele a célom.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Örülök, hogy te is így látod. Hogy miért baj? Nem maga a konstrukció a baj, mert az egy ugyanolyan unsafe megoldási lehetőség, mint az összes többi, igazából ízlés dolga. Hanem a mögötte lévő érvelés a baj (és ezért ez a válasz igazából nem is feltétenül neked szól): mert aki a "pointer-mentes" C megoldással érvel, hogy aztán az biztonságos, mivel ugye nincs benne pointer, az abban a tévképzetben lehet, hogy nem is csinálhat buffer overrun-t. De csinálhat. Pont ugyanúgy, mint a C pointer, vagy a Rust unsafe pointer.

Trollkodás helyett itt a válaszom: A feladatban egyetlen (na jó, kettő) abszolút cím van. Ez nem "szoftver element", hanem fix érték. Szerintem elég hülye az, aki - a címzés módjától függetlenül - olyan kódot képes erre írni, ami képes eltéveszteni a célt. Az abszolút címnek az a legfontosabb tulajdonsága, hogy egyszerűen ott van, mivel hardver.

Ha jól értem a szálat, gondolkodni nem akaró balfék programozók ellen kitalálnak új programnyelveket, amelyek még fegyelmezetlenebb kódolásra ösztönzik a szakma  művelésére alkalmatlanokat, amelynek hatására majd még hülyebiztosabb nyelvek lesznek, amelyekben már szinte semmit sem lehet megvalósítani, mert az úgy nem biztonságos. :(

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ha jól értem a szálat, gondolkodni nem akaró balfék programozók ellen kitalálnak új programnyelveket, amelyek még fegyelmezetlenebb kódolásra ösztönzik a szakma  művelésére alkalmatlanokat, amelynek hatására majd még hülyebiztosabb nyelvek lesznek, amelyekben már szinte semmit sem lehet megvalósítani, mert az úgy nem biztonságos. :(

A C is pont így keletkezett, ahogy leírtad, csak neked már az a baseline.

Már az assembly után? A magam részéről jól megvagyok assembly-vel is, ott inkább az a baj, hogy többféle platformra meg kell tanulni a CPU-t, ami kellemetlen, illetve ami C-ben nagyon egyszerűen, kényelmesen megfogalmazható, az azért assembly-ben egy hegymászós túra szöges bakancsban.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Meglepő módon a C a B utódja, aminek az elődje a BCPL, ami a CPL utódja, amit az ALGOL 60 inspirált, az ALGOL a FORTRAN egyik továbbfejlesztése, ami a SpeedCoding hiányosságait oldotta meg és a SpeedCoding az, amire azt lehet mondani, hogy az assembly után jött.

Mindegyik azért jött létre, mert "gondolkodni nem akaró balfék programozók ellen kitalálnak új programnyelveket, amelyek még fegyelmezetlenebb kódolásra ösztönzik a szakma  művelésére alkalmatlanokat, amelynek hatására majd még hülyebiztosabb nyelvek lesznek, amelyekben már szinte semmit sem lehet megvalósítani, mert az úgy nem biztonságos."

Nem hinném, akkoriban nem a safety volt a becsípődés, hanem a funkcionalitás kiterjesztése. Fortranról már csak nagyon halvány emlékeim vannak, tanultam, de nem használtam, de úgy rémlik, a C-nél sokkal sótlanabb, szegényesebb nyelv.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem hinném, akkoriban nem a safety volt a becsípődés, hanem a funkcionalitás kiterjesztése.

Funkcionalitás kiterjesztése? Mit nem tudtál megcsinálni Assembly-ben, amihez C kellett? A C előnye az, hogy sokkal kevesebb melóval tudsz biztonságosabb programot írni, ahogy említetted is: "ami C-ben nagyon egyszerűen, kényelmesen megfogalmazható, az azért assembly-ben egy hegymászós túra szöges bakancsban". A C egy csomó dolgot megcsinál helyetted és biztonságosabb is, mintha Assembly-ben írtad volna meg, ahol könnyen el tudsz nézni egy címkét, ahova ugranod kell és már szétesett a program.

Fortranról már csak nagyon halvány emlékeim vannak, tanultam, de nem használtam, de úgy rémlik, a C-nél sokkal sótlanabb, szegényesebb nyelv.

Szóval újra: a C azért jött létre, hogy a "gondolkodni nem akaró balfék programozók ellen kitalálnak új programnyelveket, amelyek még fegyelmezetlenebb kódolásra ösztönzik a szakma  művelésére alkalmatlanokat, amelynek hatására majd még hülyebiztosabb nyelvek lesznek, amelyekben már szinte semmit sem lehet megvalósítani, mert az úgy nem biztonságos".

A C nem egy elérendő állapot, hanem egy darab nyelv a fejlődés hosszú-hosszú útján. Aki mostanában kerül bele a szakmába, annak a Rust lesz a "C" és a C lesz az, ami neked most a Fortran és úgy nézel most a Rust-ra, mint annó a Fortran programozók a C-re. És még mindig vannak karbanartott Fortran programok...

Ha jól értem a szálat, gondolkodni nem akaró balfék programozók ellen kitalálnak új programnyelveket, amelyek még fegyelmezetlenebb kódolásra ösztönzik a szakma  művelésére alkalmatlanokat, amelynek hatására majd még hülyebiztosabb nyelvek lesznek, amelyekben már szinte semmit sem lehet megvalósítani, mert az úgy nem biztonságos. :(

Teljesen félreérted. Pl. a Rust lekorlátoz egy csomó mindenben, hogy biztonságosabb, kevesebb hiba legyen a kódban, de megadja a lehetőséget, hogy mindent megcsinálhass, ha biztos vagy abban. Pont erre való az unsafe kulcsszó.

Az alábbi hozzászólásod alapján magadat is a "gondolkodni nem akaró balfék programozók" közé sorolod?

Volt olyan, hogy switch()-ben kihagytam a break;-et egy állapotautomatában, nyilván nem működött jól, majd a logokból ...
Egy másik alkalommal char típusú változót shifteltem jobbra egy ciklusban, kilépési feltétel, ha a változó nulla. ...

Nem mondtam soha, hogy nem hibázok. Csak ne az legyen az az általános hozzáállás, hogy nyfog a fordító, rakjunk a változó neve elé egy csillagot, még mindig nyafog, tegyünk elé még egyet, most lefordult, tehát így lesz jó. Mert nagyon nem, meg kell nézni, hogyan lett deklarálva az a változó, hogyan használjuk, mert le lehet írni ilyen módon úgy is valamit, hogy lefordul ugyan, de nagyon nem az fog történni, amit szeretnénk.

Hibázni szabad, tessék megkeresni a bugot és kijavítani! Nekem egyes emberek mentalitásával van bajom, azzal, amikor félszívvel csinálnak valamit „jóvanazúgy” megközelítéssel.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Eszembe jutott még egy hibalehetőség. Nem mindegy, hogy egy tömbben sizeof()-ot vagy elemszámot használunk. Van ahol az egyikre, van, ahol a másikra van szükség. De például a konstans string sizeof()-ja meg eggyel nagyobb, mint a hossza érthető okok miatt. Itt is lehet hibát véteni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Szerinted, ha egy nem törődöm programozó csak úgy tud megírni egy kódot, hogy a fordító lépten-nyomon figyelmezteti és nem fogadja el a hibás kódot az sokkal rosszabb, mintha elsőre elfogadná és majd futás közben derül ki, ott is kétszer, háromszor elszáll, mire jó lesz?

Ezt azért gondold át!

Nem attól lesz jó egy programozó hozzáállása, hogy bármit megcsinálhat és nem kell figyelnie semmire, sőt!

Kényelmessé tesznek ezek a mesterséges korlátok, ami fegyelmezetlenséget és nemtörődömséget okoz.

Amikor fiatal voltam, nem voltak mobiltelefonok. Buták sem. Ha valakivel találkozni akartunk, s azt megbeszéltük két nappal, vagy egy héttel a találkozó előtt, akkor nem felejtettünk el odamenni, nem szóltunk oda a találkozó előtt fél órával, hogy jaj, bocs, kések egy órát, mert hullik a macskám szőre, hiszen erre nem volt lehetőségünk, hanem ott voltunk. Mindenképpen.

Ma oda lehet szólni a másiknak, ezért sokan fegyelmezetlenek, nem adják meg a másik embernek a kellő tiszteletet. Esik az eső? Nem baj, majd írok egy chat üzenetet vagy felhívom, hogy nem megyek. Az már vérmérséklet kérdése, hogy tartozik-e hozzá indoklás, egy átlátszó hazugság lesz az indok, vagy a valós, de elég rosszul csengő érv. Mindegyik nagyon rosszul hangzik. A telefon, a kommunikáció könnyebbé válása nem segített, hanem fegyelmezetlenné tett, az emberek most már nem megbízhatók.

Épp, mint az újabb programnyelveket használó programozók.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Most korbeneztem a korulottem ulo Scala, Python, Go "ujabb proframnyelveket hasznalo programozok kozott", hat a legfiatalabb 42. Mondtam nekik hogy mondtad hogy mind fegyelmezetlen halatlan pocs, mert nem C-ben irjak a kodot, hanem a faszsagaikban amik nem is igazi programnyelvek. Megkerdezem majd Csabit is aki 57, hogy mi a velemenye errol. :D

Általában írtam. Azok, akikről te beszélsz, szerintem C-ben is jó programokat írnak vagy írnának, nekik nem feltétlen szükséges a minőségi munkához a nyelv korlátoltsága. Azokról beszéltem, akik fércmunkákat adnak ki a kezeik közül, s csak a limitáció tartja hellyel-közzel megfelelő keretek között az alkotásaikat.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Azt mondom, hogy semmi baj a C nyelvvel. Nagy szabadságot enget, teret ad a fantáziának, szabadon lehet benne kódolni, nem köti meg az ember kezét. Egyesek szemében ez veszélyes, mert ők nem bíznak a kóderben. Azt mondom, aki nem hajlandó precíz munkát végezni, nem írja ki pl., hogy if (ptr) *ptr = valami;, az ne csak C-ben, de más nyelven se programozzon, hanem menjen babszemeket válogatni, arra talán alkalmas. Azzal az iránnyal van bajom, hogy hülyék ellen hülyebiztos nyelvvekkel védekezünk a szabadság rovására ahelyett, hogy igényesebb emberek művelnék ezt a szakmát.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Tegye fel a kezét aki hibátlan kódot ír mindig. Most pedig tegye fel a kezét aki szerint fontos hogy a lehető legkevesebb hibát tartalmazó kódok készüljenek el? Most pedig az, aki szerint ne a technikai hibákkal kelljen foglalkozni fejlesztés közben hanem a logikai hibákkal. Szerintem meg is válaszoltuk a kérdésre a választ. Nem, nem a hülyék miatt emeljük magasabb szintre az absztrakciót, hanem azért, hogy a lényegre tudjunk fókuszálni, az üzleti érték előállítására egy olyan iparágban ami alapvetően nagyon drága.

Nem kell ehhez kézfeltét, szépen látszik a szomszédban az általad is linkelt, és szépen figyelmen kívül hagyott cve statisztikából, hogy a valóságban milyen jól megy a memóriakezelés el nem cseszése: az overflow meg a memory corruption együtt olyan 40%, lehet tippelni, hogy vajon milyen nyelvek lehetnek ezek :)

Tegye fel a kezét aki hibátlan kódot ír mindig. Most pedig tegye fel a kezét aki szerint fontos hogy a lehető legkevesebb hibát tartalmazó kódok készüljenek el? Most pedig az, aki szerint ne a technikai hibákkal kelljen foglalkozni fejlesztés közben hanem a logikai hibákkal. Szerintem meg is válaszoltuk a kérdésre a választ. Nem, nem a hülyék miatt emeljük magasabb szintre az absztrakciót, hanem azért, hogy a lényegre tudjunk fókuszálni, az üzleti érték előállítására egy olyan iparágban ami alapvetően nagyon drága.

Azt mondom, hogy semmi baj a C nyelvvel.

Az a baj, hogy pont annyival támasztottad alá, mint egy Fortran programozó, aki szerint semmi baj a Fortran nyelvvel: pár érzelgős ezekamaifiatalozáson kívül semmivel.

Azzal az iránnyal van bajom, hogy hülyék ellen hülyebiztos nyelvvekkel védekezünk a szabadság rovására ahelyett, hogy igényesebb emberek művelnék ezt a szakmát.

A C nyelv pont így és pont azért keletkezett, hogy kényelmesebb és hülyebiztosabb legyen, mint az elődei. A saját definíciód szerint te pont ugyanúgy egy hülyébb világ kényelmes hülyéje vagy, csak az életkorodból adódan máshol húztad meg az alapvonalat: nem a Fortran-nál, hanem a C-nél. Ha korábban születsz, akkor Fortran programozó lettél volna, ha később, akkor a Rust lenne az alapvonalad.

Szerintem a C nem hülyebiztos.

Mihez képest? A BCPL-hez képest? Az Algol-hoz képest? Az Assembly-hez képest? Ezekhez képest mind hülyebiztosabb a C nyelv, mert egy csomó könnyű tévedési lehetőséget lehetetlenné tett, szóval még mindig ott tartunk, hogy a saját definíciód szerint hülyébb világ hülyéje vagy egy tetszőleges Fortran programozóhoz képest, mert neki sokkal több könnyű tévedési lehetőségre oda kellett figyelnie, amire neked C programozóként már nem kell, mert a nyelv maga megakadályozza a könnyű tévedések jelentős részét.

Te egyszerűen beleszülettél egy hosszú fejlődési folyamat egyik állapotába és ahhoz ragaszkodsz, pusztán szubjektív okokból. Ha kicsit előbb születsz, akkor most a Fortran-t védenéd a C-vel szemben, és vernéd az asztalt, hogy a C elhülyült hátulgombolósoknak való játékszer, az igazi programozó Fortran-ban írja a programot.

A C-nek nem a korlátoltsága a lényege az assembly-vel szemben, hiszen C-ben lehet csinálni inline assembly tartalmú makrót, ha valami hiányozna. A C lényege a közérthetőbb, egyszerűbb, áttekinthetőbb megfogalmazás, adott esetben hordozhatóság. Viszont megmaradt benne a szabadság.

Ami nekem a történetben fáj, az a szabadság elvétele. Ugyanez a bajom a különféle iparági jogszabályokkal, limitációkkal, szabványokkal, auditálásokkal. A fürdővízzel kiöntik a gyereket is. Ezek a szabályok olyan elvárásokat támasztanak a munkaadó felé, hogy a munkafeltételeket is keretek közé zárják, a munkavállaló irányába kedvezőbb, jobb munkafeltételeket akkor sem biztosíthat a munkáltató, ha egyébként szeretne. A szabadság elvesztése nem csak itt, hanem minden területen érzékelhető. Akkor, amikor megjelenik az elektronikus pénz, az okostelefonok GPS vevővel, hálózati kapcsolattal, kamerákkal, az utcai kamerák, a különféle iparági szabályozók, a minősített személyes adatok kötelező nyilvántartása, ideértve az EESZT-t vagy a szálláshelyeken történő személyi fénymásolását, az authentikációs technológiákat okostelefonokra valósítják meg egyre inkább, egyre nehezebben kerülhető ez meg, folyamatosan sérül a privacy, akkor szerintem nagy baj van a társadalommal és a szabadsággal. Miközben cinikusan épp a nyugati világ nevezi magát szabad világnak, bár ez ismerős, mert 1989 előtt a legjobb, legszabadabb társadalmi berendezkedés a szocializmus volt, legalább is nálunk.

Ebben a sorban élem meg veszteségként, a szabadság szűküléseként az újabb nyelveket.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A C-nek nem a korlátoltsága a lényege az assembly-vel szemben, hiszen C-ben lehet csinálni inline assembly tartalmú makrót, ha valami hiányozna.

Na, látod? Saját magad vallod be, hogy korlátoz, különben nem lenne szükség inline assembly lehetőségre.

A C lényege a közérthetőbb, egyszerűbb, áttekinthetőbb megfogalmazás, adott esetben hordozhatóság. Viszont megmaradt benne a szabadság.

Jobb, mint a mi? A Fortran? A BCPL? Az Assembly? A Rust? Állandóan olyan összehasonlításokat teszel, aminek nincs a másik oldalán semmi, nem írod le, hogy mihez képest, nincs objektív horgonyként működő szempontod, különben a logikád szerint csak és kizárólag gépi kód létezne, minden más ahhoz képest a kontroll és szabadság elvesztése.

Nem mered leírni, hogy számodra egy kényelmes kompromisszum a C nyelv az elvett szabadság és a gyorsabb munka között, mert akkor szembe kellene nézned azzal, hogy ugyanúgy egy hülyébb világ kényelmes hülyéje vagy, csak az életkorodból adódan máshol húztad meg az alapvonalat.

Ami nekem a történetben fáj, az a szabadság elvétele.

A C is pont egy ilyen elvett szabadságról szól, csak beleszülettél, számodra természetes. Te nem a még szabadabb dolgokra vágysz, különben nem C nyelvet használnál, hanem arra, hogy maradjon minden úgy, ahogy abba beleszülettél. Tudod, ha hallgattunk volna a Fortran programozók hasonló sírására, akkor ma nem lenne C nyelv.

Ahhoz, hogy legyen egy INTERRUPT_GlobalInterruptEnable(); makród, előbb-utóbb kell inline assembly, de ez éppen meg van engedve a C-ben, tehát nem korlátoz. Vagy például RESET(), esetleg NOP().

Nincs bajom a Rusttal, nem ismerem, így nem is lehet. A gondom a nyomásgyakorlás. Nem mindegy, hogy valakinek megtetszik, majd használni kezdi, vagy ajánlásokat, előírásokat fogalmaznak meg mindenféle hangok, hatalmasságok. Nem a fejlődést tartom rossznak, hanem a kényszerítést.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ahhoz, hogy legyen egy INTERRUPT_GlobalInterruptEnable(); makród, előbb-utóbb kell inline assembly, de ez éppen meg van engedve a C-ben, tehát nem korlátoz. Vagy például RESET(), esetleg NOP().

Aha-aha, látod: az elvesztett szabadság van így-úgy visszadrótózva, hozzákötözve vagy csak mellé téve, mert a C nyelv erre önmagában nem képes.

Nincs bajom a Rusttal, nem ismerem, így nem is lehet.

Tehát egészen eddig olyan dolog miatt nyafogtál, amiről halvány fogalmad nincs, hogy jobb-e vagy sem? A mindenszarizmus vegytiszta megnyilvánulása. :D

A gondom a nyomásgyakorlás. Nem mindegy, hogy valakinek megtetszik, majd használni kezdi, vagy ajánlásokat, előírásokat fogalmaznak meg mindenféle hangok, hatalmasságok. Nem a fejlődést tartom rossznak, hanem a kényszerítést.

Nincs nyomásgyakorlás, a Fortran is él és virul ott, ahol még megvan a helye. A C is ilyen lesz, sőt, a Rust is ilyen lesz 5-10-15-20 év múlva, amikor jön egy még újabb nyelv, ami még több hasznos választ ad arra, amit a korábbi nyelvek nem tudtak megválaszolni. Nyelvek jönnek és mennek, neked ezzel a változással van bajod, azt sírod vissza az élet minden területén, ami a gyerekkorod vagy fiatal felnőttkorodra jellemző volt. Nem objektív mércével méred, érvelve és tényeket felsorakoztatva, hanem egy nagyon durván szubjektív mércével mérsz mindent és teljesen értetlenül állsz pislogva, amikor kiderül, hogy másoknak is vannak nagyon durván szubjektív mércéi.

hiszen C-ben lehet csinálni inline assembly tartalmú makrót, ha valami hiányozna.

Nem, ezt a C szabvány nem támogatja, C-ben nem tudsz ilyet csinálni. Legfeljebb az egyes C fordítók támogatják az inline assembly-t különféle nyelvi kiterjesztéseken keresztül (de ez akkor már nem C), olyan módon, hogy az nem lesz alapesetben hordozható a fordítók között.

A túlszabályozással csak agyonagyminisztráltan, rossz kedvvel, kényszerek között teszed meg a szükséges minimumot úgy, hogy még kedved sincs odafigyelni, mert elvették a szabadságod. Persze tudom, van akinek ez belefér, hiszen vannak nagy multicégeknél dolgozó emberek. Én nem vagyok erre alkalmas.

Azt nem tudom, hogy az általad említett fickó miért halt meg abban a tengeralattjáróban, úgy értve, hol és ki, milyen oknál fogva követte el azt a hibát, ami miatt nem bírta ki a cucc a hatalmas, de ismert és így számolható nyomást.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

hol és ki, milyen oknál fogva követte el azt a hibát, ami miatt nem bírta ki a cucc a hatalmas, de ismert és így számolható nyomást.

A Titan balesete kapcsán érdemes megjegyezni, hogy a Titant semmilyen szervezet nem vizsgálta, nem volt tanúsítva arra, hogy használható vízben, mindenki, aki felszállt rá, alá kellett írjon egy olyan felelősségi nyilatkozatot, miszerint ez egy kísérleti eszköz, ami nincs bevizsgálva, és a halál egy olyan kockázat, amivel számolnia kell.

Mindezt úgy, hogy a cég operatív igazgatója kérte, hogy vizsgálják be és tanúsíttassák az eszközt, de ezt a cég nem akarta kifizetni. Utólag kiderült, hogy a kabinablak a tervezett mélység egyharmadát sem bírta ki.

2020-ban maga Rush mondta azt, hogy a Titant legfeljebb 3000 méteres mélységig lehetne csak használni, mert anyagfáradás jeleit mutatja - ki is kellett cserélni a burkolatot.

A nagy okos mérnökök a gyorsan, ügyesen, olcsón jegyében szartak mindenféle biztonsági előírásra, és kész is lett a katasztrófa. Tudták ők pontosan, hogy mit kéne gyártani, csak hát a mérnöki szabadságuk oltárán feláldozták a biztonságot.

Ha nem vagy arra alkalmas, hogy betartsál biztonsági előírásokat, akkor remélem, hogy nem használom az általad írt szoftvert.

Szerintem nem fogod tudni, mikor használod az általam írt software-t. :)

Egyébként nem értek egyet a mondandóddal. Sohasem a mérnök az, aki ki akar mindent spórolni. Jellemzően fentről jön a nyomás, közgazdászoktól, managerektől, a board felől, akik úgy gondolkodnak, hogy ha egy nő egy gyereket kilenc hónap alatt, akkor kilenc nő egy gyereket majd nyilván egy hónap alatt.

A mérnök kiszámolja, megtervezi jól, aztán felteszik a kérdést, ez mennyibe fog kerülni. Ja, akkor azt úgy nem lehet, meg kell oldani olcsón okosba'. Ebből a szempontból volt értelme a Titán katasztrófájának, mert megmutatta a közgazdászoknak, pénzembereknek, hogy a Teremtőt nem lehet pénzzel megvesztegetni, sok pénzzel sem lehet a fizikai törvényszerűségeket megváltoztatni.

Ha a bevizsgálásra elpacsálnak egy rakás pénzt, a Titán megbukik, akkor az a pénz elveszett az alkotók számára. Tehát nem a bevizsgálásra kellett volna költeni, hanem a saját mérnökeiket kell meghallgatni, s el kellene nekik hinni, hogy ők nem fizetett ellenségek a cégen belül, hanem tényleg drága dolog egy ilyen cuccot jól, megbízhatóan megcsinálni. Nem biztos, hogy jó ötlet minden csavart folyáshatárig terhelni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Sohasem a mérnök az, aki ki akar mindent spórolni.

Te mondtad azt, hogy pont te szeretnéd megspórolni a mindenféle visszakövethetőség és más egyéb minőségbiztosítás miatti adminisztrációt, nem szereted a jogszabályokat sem stb. Tudom, ez mind idő, és mind költség, és meg akarod spórolni.

Sikeres emberek gyakran osszetevesztik az altaluk elert sikert a mindenhez IS ertek tulajdonsaggal. Ez vezetett a Titan katasztrofajahoz. Egy arrogans fasz miatt meghalt par ember akiket sikeresen felrevezetett a bullshit dumajaval.

Amugy vannak iparagak ahol ha hosszu ideig tart egy termek bevizsgalasa annak megvan a miertje. A mi implantatumainkat is hosszu faradalmas eljarasok "gatoljak" piacradobas elott. De ez igy van jol. En sem szeretnem a vasarloink helyeben, hogy mindenfele uttoro megoldast epitsenek a fejembe mindenfele bevizsgalas nelkul mert az ugy innovativ meg olcsobb egy cegnek.

Ami nekem a történetben fáj, az a szabadság elvétele.

Értem. Tehát az a tény, hogy míg assemblyben oda ugrálgatsz JUMP parancsokkal a memóriában, ahová akarsz, addig C-ben a goto-val max. függvényen belül lehet ugrálgatni, az a szabadság elvétele, és ez neked fáj -> tehát le a C nyelvvel!

Hogy is van a régi vicc? ̈"Örökös verseny van a programozók és az univerzum között - a programozók igyekeznek egyre inkább hülyebiztos programokat készíteni, az univerzum pedig egyre fejlettebb és fejlettebb hüyéket igyekszik előállítani. De egyelőre az univerzum van nyerésben."

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

A katonák jutnak eszembe, ott a rengeteg korlát és szabály, amitől iszonyat fegyelmezetlenek. Ja, nem.

Azt hiszem pont az ellenkezőjét bizonyítod. Minél több a lehetőség, minél kényelmesebb megcsinálni valamit, annál könnyebb fegyelmezetlennek lenni.

Ha valakivel megbeszéled, hogy találkozni akarsz, majd ezután, ha akarod, ha nem el kell menjél, ez jelenti a korlátozást. Sokkal jobban meg fogod gondolni, hogy megbeszélsz-e egy találkozót, mintha nem lenne kötelező elmenned.

Az, hogy egy nyelvben számtalan dolog le van korlátozva, az nem azt jelenti, hogy kevesebbet tudsz vele megvalósítani.
Pl. ott a Rust, van rengeteg korlát, de az unsafe-fel a korlátok alól felszabadít.

Illetve érdemes lenne megnézned ezt a videót: Constraints Liberate, Liberties Constrain — Runar Bjarnason

A korlátozás, egy másik absztrakciós szinten, hatalmas szabadságot ad, illetve fordítva is, a szabadság pedig nagyon lekorlátoz.

A korlátozás, egy másik absztrakciós szinten, hatalmas szabadságot ad, illetve fordítva is, a szabadság pedig nagyon lekorlátoz.

Ezzel nem értek egyet. Ha ott a szabadság, még mindig lehetek mazochista meggyőződésből, és fogadhatok cölibátust, mondhatom, hogy márpedig nem használom a malloc(), free() párost, vagy megesküdhetek a szomszédom életére, hogy minden tömbindexet megvizsgálok range-re, if ()-ben, while ()-ban nem használok értékadást, és így tovább.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Csak hogy erre semmilyen bizonyitékot nem tudsz szolgáltatni, és itt van a kutya elhantolva. Egy magas szintű nyelv biztosítani fogja hogy azt csinálja amit kell, egy formális bizonyítást biztosító nyelv pedig bizonyítani is fogja. Szerintem a különbség érezhető. 

amikor a nagy cegnel 1200 dev 250+ team-ben fejlesztget, teljesen mas perspektiva, mint amikor otthon esp-t butykolok egymagam estenkent.

sokkal tobbet szamit, hogy *kiszamithato* legyen a kod. mert az igazi koltseg a developer, a security problemak, meg ugye a hibajavitas, nem az, hogy esetleg 30-40%-al tobb cpu ido alatt fut le valami.

Ahol tenylegesen husbavago a 30-40% -nyi cpu ido megtakaritas, ott raallnak es leoptimalizaljak. de csak azt az 5%-ot.

 

ugyszinten, ilyen leptekben bejonnek a HR dolgok is, nevezetesen: ugyan honnan a rakbol szerzel te 1200 developert. Bizony, hidd el, nem all az utcan 1200 tapasztalt c++ developer, hogy nalad dolgozzon. Ha meg be kell tanitani, hirtelen kurvafontos szempont a nyelv tanulhatosaga. Itt villant nagyot a python es a go. Meg azok a programnyelvek/platformok, amiket felsofoku oktatasi intezmenyekben oktatnak. Mert az mar megvan, azt mar nem kell extraban tanitani.

 

tl;dr: nagy leptekben hirtelen teljesen atalakul a szoftverfejlesztes. de ugy tenyleg *teljesen*.

Szerintem elég hülye az, aki - a címzés módjától függetlenül - olyan kódot képes erre írni, ami képes eltéveszteni a célt.

Ugye tisztában vagy vele, hogy a C nyelven írt programokban lévő bugok és kihasználható sebezhetőségek túlnyomó része pontosan emiatt létezik? :D

Hiba sokféle lehet. Volt olyan, hogy switch()-ben kihagytam a break;-et egy állapotautomatában, nyilván nem működött jól, majd a logokból vált gyanússá - milyen jó, hogy teszek a logba időbélyeget -, hogy a két állapot között irreálisan kevés idő, alig néhány µs telik el csupán. Az meg csak úgy lehet, ha az egyik állapotból belefut a másikba. Mégsem lehetetleníteném el switch()-ben a break; hiányát, van, hogy aktívan élek vele, időkritikus helyeken jól jön az. Mikrokontrolleres környezetben ilyen helyzet pedig adódik bőven.

Egy másik alkalommal char típusú változót shifteltem jobbra egy ciklusban, kilépési feltétel, ha a változó nulla. Aztán egyes esetekben működött jól, más esetekben watchdog reset lett. Ugye, a char az signed, aritmetikai shiftelést fordít a compiler, negatív számnál pedig 0xff lesz a végén, és így is marad örökre, az meg sohasem lesz nulla. Pozitív argumentum esetében meg ugye jól működött. A megoldás természetesen unsigned char. Az egész gép fejre állt tőle, és még csak pointernek sem kellett benne lenni. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Hát persze,könnyen előfordul, ha kelleténél több az absztrakció. Példa: Úgy adtam át a mérési eredményeket, hogy a fogadónak elegendő lett volna az xyz koordináta/pointer ráhúzása. Ennek ellenére a C# tudor aki "nem szereti az unmanaged dolgokat" egy-egy buffert listába rak, mert ott az a szokás. Aztán mégis előfordult némi szívás vele. ;) A másik, amikor 30-40 oldalas C drivert tettem át 30-35 soros assembler kódra. Komolyan mondom, hogy abban az olvashatatlan C kódban egy egész csomó hibát vétettem volna.

Hiába a 20+ év C tapasztalat, 40 év assembler után a C kódom is assembler szemüveggel készül. ;)

Le a kalappal a feladat kiíró előtt! Rendesen szivatja a társaságot, mert sikerült olyan feldatot kitalálni, amit normális ember assemblerben ír meg,maximum néhány sor C-ben. Persze láttam már vezérlést sql-ben is futni. Szóval nincs lehetetlen!

Úgy adtam át a mérési eredményeket, hogy a fogadónak elegendő lett volna az xyz koordináta/pointer ráhúzása.

Azért azzal óvatosan, ha struktúrát adunk át lényegében típustalanul, meg rábökünk egy pointerrel, mert akkor lehetőleg packed legyen, nem túl nagy baj, ha mindkét oldalon ugyanúgy kis- vagy nagyindiános :), a pointerek mérete ugyanakkora, mert különben baj lesz.

a C kódom is assembler szemüveggel készül

Ez így normális, az esetemben is így van. Eleve nehéz lehet úgy programot írni, ha valaki nem érti, hogyan működik a számítógép, illetve szorosabban véve az az architektúra. Persze nyilván sok réteggel feljebb, amikor csak libek és oprendszer van, ez egyre kevésbé érdekes.

Persze láttam már vezérlést sql-ben is futni. Szóval nincs lehetetlen!

Meséltem, hogy awk-val és gnuplottal csináltam oszcilloszkópot, ami termikus folyamat idődiagramját jelezte ki valós időben? :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Azért azzal óvatosan

Az óvatosság helyett jól működik a specifikáció is. ;)

Eleve nehéz lehet úgy programot írni, ha valaki nem érti, hogyan működik a számítógép, illetve szorosabban véve az az architektúra.

Ej, minek az! - gondolta Stirlitz. Volt egy kolléga, aki a Számalkban volt C tanár, de úgy hitte, hogy multitasking csak a VAX processzorán valósítható meg.

A feladat kiírása tiltja az inline assembly alkalmazását. Vagyis a megoldáshoz a C sem alkalmas, mert esetleg nem minden utasítást implementál a fordító.

És jön a mizéria: Hűha! Interrupt! - Amit legkevésbé sem értek, hiszen pontosan definiált a működése. És ez egy olyan kérdés, amit akár a gyártók egyes szakemberei is misztifikálnak és óvatosságra intenek, jótanácsokkal látnak el. ;)

Oszcilloszkóp? Én meg konfigot olvastam és telnetes felületen jó néhány menün keresztül routert programoztam a nulláról - awk-val. Csak azon múlik, hogy hova kötöd az stdin, stdout és stderr csatornákat. Jut eszembe, hasonó módszerrel programoztam 192 terminált és a hozzájuk tartozó terminálszerver csatornát is.

Tehát továbbra is igaznak tartom

Dehogy tartod, Te magad írtad, hogy a megoldásodnál: normál visszatérés egy normál függvényből. Na de erre meg a kutya sem lenne kíváncsi, engem egész biztos tuti nem érdekel.
Talán az ICCC-be is belekötsz, hogy a pályaművek nem karbantarthatóak? Ugye, hogy nem, pedig a karbantarthatóság milyen fontos szempont!

Még egyszer, utoljára: a feladat nem az, hogy atombiztos megszakításkezelést csinálj, hanem hogy minnél kevesebb gányolással oldd meg alapértelmezett qemu környezetben.

De, igaznak tartom, hidd el, hogy, az eddigiek alapján magabiztosan el tudom dönteni, hogy mit tartok igaznak. A rendszerprogramozás mint fogalom nemcsak azokból a kódsorokból áll, amikor közvetlenül belépsz az interrupt kezelő függvénybe. Felesleges erről tovább érvelni.

Én értem, mi a feladat, amit te kiírtál. Meg is oldottam, nagyjából a te játékszabályaid szerint.

De mindettől még állíthatom, sőt talán csak ezek után állíthatom igazán, hogy a feladatkiírásod szenved ettől a problémától, egyszerűen jó programot nem így írunk, és ezt te is beláttad közben a korábbi hozzászólásaidban, csak egyszerűen a nagy erőlködésedben muszáj voltál beleraknod és bennehagynod valami olyan csavart a feladatkiírásba, amiről azt hitted, hogy csak C-ben lehet megoldani. Nem jött be. Pont ugyanúgy kell körbetaknyolni Rust-ban, mint C-ben. És még ezek után sem akarod belátni, hogy ehhez lehetne máshogy is hozzáállni.

És csak hab a tortán, hogy ezt írod:

 minnél kevesebb gányolással oldd meg

Lásd be, hogy az általad megálmodott interrupt kezelési módszer a legnagyobb gányolás az egészben. Bizonyítja ezt az összes eddigi megoldás, a tieid is, mindegyik azon a ponton törékeny.

És megintcsak persze, de elfelejted, hogy a kifejezés végére muszáj visszaállítani a stack pointert a kifejezés előttire, különben nem működhetne a program. Magyarán olyan, mintha nem is változott volna a stack.

Látott már valaki ilyet C fordítótól? Mármint hogy a kifejezés végén (függvényhívást leszámítva, mert az ABI specifikus igény lehet) a stackframe-hez nyúl. Mert én még nem. (Csak ezt demonstráló C kódot, ill. generált asm-et fogadok el valid válasznak.)

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Mert én még nem.

Akkor nézd meg alaposabban, ez minden fordítónál (nemcsak C) alapelvárás. Optimalizáció során mindössze annyi történhet, hogy nem teszi ki külön-külön az utasítást, hanem egybevonja, de mint említettem volt, ez már optimalizáció.

Olvasnivaló:
https://www.cs.princeton.edu/~appel/modern/c/
https://online.stanford.edu/courses/soe-ycscs1-compilers

Kicsit lazább, könnyebben érthető cikkek:
https://hackaday.com/2022/11/27/create-a-compiler-step-by-step/
https://www.guru99.com/compiler-tutorial.html
https://norasandler.com/2017/11/29/Write-a-Compiler.html

Régi, m68k-ra fordít, de szerintem máig az egyik legjobb és legkönnyebben érthető anyag a témában:
https://compilers.iecc.com/crenshaw/

Te most tényleg belinkeltél nekem egy csomó hogyműködik egy fordító kezdőknek tutoriált? Ha már fölényeskedünk, elmondanám, hogy jórészt én írtam a Free Pascal jelenlegi Motorola 68k kódgenerátorát, meg vagy féltucat OS portját. Eközben olvastam "néhányszor" C fordító által generált kódot, kb. féltucat különböző platformon, az x86-okat is ideértve. Szóval szerintem - az eddig elhangzottak alapján meg főleg - nem nekem kéne utánaolvasnom, hogy egy fordító hogy is működik.

De befejeztem, mert ez már arra megy ki, hogy ki miért hülye, nem technikai megoldások boncolgatására és megvitatására.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Nem állt szándékomban megsérteni.
Sajnos itt a HUP-on sokaknál van alacsonyan a színvonal, ezért linkeltem reflexből könnyen érthető tutorialokat is, de mégegyszer, ezzel nem akartam esetlegesen a hozzáértésedre utalni vagy bármi módon azt suggalni, hogy hülye lennél. Ha így jött volna le, akkor biztosíthatlak, nem ez volt a szándék.

Elnézést!

Szerkesztve: 2024. 03. 12., k – 15:27

Közben érkezett egy C megoldás, ráadásul mindjárt MSVC-s, PE/COFF-os, így már többféle ABI-nk is van!

Mivel született mástól C megoldás, így most már feltehettem a saját megoldásaimat:
elf - natív fordítóval (nem cross-compiler gcc, de megy Clang-al is),
pe - cross-compiled Clang-al,
noptr - siránkozóknak egy teljesen pointermentes megoldás.

Ha bunkó akarnék lenni, akkor most azt mondanám, hogy tessék, itt a pointer mentes C megoldás, hol az unsafe mentes Rust megoldás? :-D De csak viccelek!

A Lisp-ek általában interpreterek ugyan (pl. a "hivatalos" Common Lisp), de elég sok Lisp fordító is létezik, amik natív kódot képesek generálni (pl. GNU CLisp is tud ilyent), úgyhogy legalábbis elméletben nem látom akadályát.
Valóban érdekes lenne látni egy Lisp-es megoldást is!

Azt nem mondom, hogy az általatok megírt C, Pascal forrásokat is teljesen értem. De nagyjából megvan az kép, hogy hogyan áll össze a dolog a fordítóval, linkerrel, betöltővel meg az ELF/PE fájlból. Lisp esetén viszont elképzelésem nincs, hogy hogyan nézne ki. Írtam már kisebb Lisp programokat és tudom, hogy a legtöbb Lisp tud natív kódra fordítani, de hogy ebből hogy lesz egy ELF pl.?! Vagy milyen nyelvi elemek vannak, amivel ezt meg lehet oldani.

Amugy minek fektetsz ennyi energiat ebbe?

Majd ha lejárt a határidő, ígérem, elárulom. Addig legyen elég annyi, hogy tökéletesen hozza azt, amire terveztem ;-)

Na, ez tényleg nem piskóta, Adams85 egy igazi csemegével szolgált, C# megoldást küldött be.

Azoknak, akik nem tudnák, ez azért iszonyat nagy szó, mert a C# alapból bájtkódra fordít, pont mint a Java, szóval ez egy igazi bravúr!

Hát elismerem, a kolléga talált egy kiskaput és végül is nem sértette meg a szabályokat. Így fogalmaztam ugyanis:

inline Assembly nem, csak az adott nyelv natív utasításkészlete használható, a forrásnak hordozhatónak kell lennie (azaz hiba nélkül le kell fordulnia többféle architektúrán, akkor is, ha úgysem működne ott)

A szándék valóban az volt, hogy ne érjen semmi ilyesmi, de a bájttömb tényleg hiba nélkül lefordul bármilyen architektúrán. Szóval ha szigorúan tartom magam a szabály szövegéhez, akkor el kell ismernem, ügyesen túljárt az eszemen!

(ps: kizárni emiatt ugyan nem lehet, de mindenképp gányolt megoldásnak minősül, ezért nem lehet ez a befutó. De ettől függetlenül is írtó hatalmas riszpekt az alkotónak!)

Elvileg lefordítható a C# bájtkód helyett LLVM kódra, majd onnan natív x86_64 binárisra, de nem csináltam még ilyet.

Egyébként én amondó vagyok most már, hogy át kell térned Rust-ra. Soydevek szépen megírták neked a soványka 13 gigás (!!!), röpke időn belül leforduló kódbázisát, ha nem használod, pocsékba megy. Szépen használni a bloat-ot, mert az úgy biztonságosch. Ha ilyen csóró C-ben tolod, akkor elvesztik a munkájukat a Rust-ot fejlesztők, nem lesz szükség tovább az általuk megteremtett szép komplexitásra.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Elvileg lefordítható a C# bájtkód helyett LLVM kódra, majd onnan natív x86_64 binárisra

Nemcsak elméletben, a kolléga megoldása pont ezt demonstrálta a gyakorlatban. Úgy tudtam, ez csak 3rd party tool-al lehetséges, de mint kiderült, egy-két éve bekerült a fordítási környezet alapfunkciói közé.

Lett egy Golang megoldás! :-)

A kolléga töredelmesen bevalotta, hogy a standard go alkalmatlan volt a feladatra, de azért mindenképp kijár a tisztelet az alkotónak, hogy addig nem adta fel, míg mindenre nem talált valamilyen kerülőmegoldást.
A beadott program végül nem használja egyáltalán az interfészt (linkerszkriptes fixcímes hekk van helyette) és tinygo-val fodul, de működik!

Hacsak nem felejtettem ki valamit, akkor asszem a jelenleg agyonhájpolt nyelvek közül már csak a Zig hiányzik a felhozatalból.

Ne haragudj, de milyen elfogult értékelési szempont az, amiben az számít, hogy mekkora a lefordított program és hány kulcsszó használatával készült el? A való életben szerinted a programozási feladatok kb. mekkora részében szempont ez egyáltalán (és mennyiben fontos, és mennyiben kizárólagos szempont)?

Ráadásul ez alapján akarod azt mondani, hogy egyik vagy másik programnyelv jobb, mint a másik.

Én nagyon régen nem programozom, a kiírt feladatot C-ben se tudnám megírni jelentős olvasgatás nélkül (pl. fogalmam sincs, hogy hogyan kellene a video memóriába írni a választott platformon). De évtizedek távlatából is emlékszem, hogy a feladathoz választunk eszközt, pl. programnyelvet. Biztos vagyok benne, hogy van egy csomó feladat, amihez a C a legjobb, vagy az egyik legjobb. Ez nem jelenti azt, hogy minden feladathoz a C a legjobb. C helyére tetszőleges nyelv behelyettesíthető itt fent.

Video memóriába utoljára assemblyből írtam direktben (nem PC platformon). Ahogy emlékszem, PC-s haver assembly-ből BIOS hívásokkal írt a képernyőre, de pl. C-ből már nem csináltunk ilyesmit, hanem az OS által adott lehetőségeket használva írtunk ki dolgokat.
Pont azért kezdtünk el C-t használni, mert a méretre optimalizálás már nem volt fontos szempont, fontosabb volt, hogy gyorsabban, jobban karbantartható, jobban átlátható, kevesebb hibát tartalmazó és hordozható legyen a program. És pont ezért váltottam később C/C++-ról Pythonra.

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

Részben egyetértek veled, de nagyon nem mindegy a lefordult kód mérete, futásideje. Írtál programot picike mikrokontrollerre? C-ben írva 90 %-os tárhely kihasználásnál elkezdesz reménykedni, hogy nem kell új feature-t írni bele, s az a 10 % elég lesz az esetlegesen meglévő hibák javítására. Valamint nem azon gondolkodsz, hogy rustban kellene írni, hanem inkább azon, hogy ez assembly-ben kijött volna a kétharmadából, s közel kerülsz az érzéshez, hogy átkozd a pillanatot, amikor nem assembly-ben, hanem C-ben kezdted el a munkát. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Van ilyenre konkrét példád?

Ugye ha elérünk egy bonyolultsági szintet, akkor hirtelen nagyon sok munka ASM-ben befejezni a programot, és ha közben optimalizálni is kell, akkor pláne végtelen szívássá válhat. Vannak például ilyen "legygorsabb ez-az" versenyek, a generátor template-ekkel és web szerverekkel foglalkoztam egy kicsit. Mindkettő esetén az van, hogy a top megoldások kihasználják a lehetőségek maximumát, és ott akadnak el.

Idén volt a "1 billion row challenge", érdemes megnézni milyen trükköket használtak a legjobb megoldások: ASM-ben írva is lényegében csak a JVM indítás overheadjén tudnánk faragni, ami nem sok lévén hogy binárisra fordítós JVM-et használtak a legjobbak. A nem-Java megoldások sem tudtak sokkal gyorsabbak lenni úgy tudom, bár rendes összehasonlító táblázatot nem találtam.

A template engineket például Java nyelvre néztem - bevallom megpróbáltam gyorsabbat csinálni mint a leggyorsabb itt és utolérni sikerült, de legyorsulni nem: https://github.com/agentgt/template-benchmark - , és a benchmarknak a legjobbak esetén az lett a bottleneckje, hogy Java stringet kell visszaadni és a bájtfolyamból Java string objektum készítés meglehetősen időigényes, lassú folyamat. Amint ez lesz a bottleneck, ott nincs mit tenni, nem lehet tovább javítani a teljesítményt a platform fejlesztése nélkül. Mivel a string kezelés körülményes és lassú Javában, ezért template nyelvből szerintem sokkal gyorsabbat lehet csinálni C-ben. Kivéve, ha Javában is úgy döntünk, hogy mostantól a string az csak egy MemorySegment. Újra kell írni az összes String formázó API-t, de a végén a C-vel/ASM-mel pariban lehetünk teljesítményben. És ha csak a szűk keresztmetszetet optimalizáljuk így ki, akkor összességében még mindig kevesebbet dolgoztunk mintha teljesen C-ben vagy akár ASM-ben indultunk volna el.

A web szerverek esetén jóval a RAM sávszélesség előtt a kernelhívások overheadje lett a szűk keresztmetszet. Lényegében a kiszolgáláshoz szükséges kernelhívásokat mérte a benchmark a legjobb versenyzők esetén. Mivel ez lett a szűk keresztmetszet, ezért ASM-ben írva sem tudtam volna jelentősen jobb eredményt elérni mint a legjobb Java megvalósítás - és a pályamű évek munkája lett volna nyilván ASM-ben.

Két fajta válasz is lett erre a problémára. Az egyik az io_uring API, ami arra ad lehetőséget, hogy sokkal kevesebb kernel kontextusváltással tudunk átadni IO parancsokat a kernelnek. Aki ezt először be tudta építeni a megoldásába az hirtelen hülyére verte a többit.

A másik válasz az volt, hogy tegyük be a http szervert a kernelbe! Amennyire unortodoxnak hangzik, én néha tényleg nem értem, hogy ha egy szerver 1 dolgot csinál, akkor miért is kell a kernelt védeni a userspace-től? Hiszen minden ami fontos úgyis a userspace-ben van, nem? Tegyünk inkább mindent a Kernelbe, kapcsoljuk ki a kernel védelmeit a fenébe, és lássunk csodát micsoda teljesítményeket lehet elérni így!

De ezek már más méretskálán vannak mint locsemege mikrovezérlős dolgai.

tényleg nem értem, hogy ha egy szerver 1 dolgot csinál, akkor miért is kell a kernelt védeni a userspace-től?

A kernelbe lehetőleg nagyon jól karbantartható, optimalizált, áttekinthető, stabil megoldások valók, mert ha ott elhasal valami, akkor beleállt a földbe a gép. Userspace-ben legfeljebb a kernel exception handlere kivágja az alkalmazást, ha az valami butaságot csinál, de a gép stabil marad.

Persze, ha az egy dolgot csinál kritériumot úgy érted, hogy még adminisztrációs tool-ok sincsenek, akkor az egyik lehetőség az, hogy nem kell védett mód, pl. fusson valami DOS-féleségen az a szerver, vagy szintén oprendszer nélkül egy mikrokontrolleren.

Nekem sincs kernel a fenekem alatt még 32 bites MIPS-en sem.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Értem én, hogy miért van, csak amikor méregeted, vagy benchmarkokon gondolkodsz és az elméleti maximumot nagyon nem tudod kihasználni (RAM, Ethernet, stb) akkor rájössz, hogy megvetted a vasat meg fizeted az áramot és az idő legnagyobb részében "context switch"-eket finanszírozol. Azért, hogy védd a kernelt, amiben semmi több nincs mint magában az alkalmazásban. valójában értelmetlenségekre megy el az erő.

Nyilván nem a hobbi weboldalakról beszélek ahol ez mindegy, hanem ahol rohadt sokat kell kiszolgálni, például olvastam régen, hogy hogyan streamel a Netflix filmet https-en át. Ott egy stream szerver nem csinál mást, csak streamel, és tényleg a Kernel hívások a szűk keresztmetszet. Amióta olvastam ezeket a cikkeket, azóta szerintem mainstream lett az uring, tehát ez a kérdés talán már meg is van oldva. De érdekes belegondolni általánosságban, hogy az a rengeteg overhead amit "kifizetsz" a Kernelért, az valóban kell-e neked?

Például nekem is van egy megoldandó teljesítmény problémám, aminek hasonló oka van - túl sok kernel hívás - és megoldhatatlan problémának látszik. Pedig megtehetném, hogy a gépen csak az az egy program fut, és még a processz-izolációról is le tudnék mondani, ha lenne rá működő technika amit ki lehet rántani a kalapból.

Van ilyenre konkrét példád?

Pont ma jött szembe: Top 5 Fastest Programming Languages: Rust, C++, Swift, Java, and 90 more compared!

Kb. 10.40-nél kezd el beszélni a C-ről és azon belül, 13.15-től beszél arról, hogy az Assembly nem tudott az 5 közé kerülni és ennek mi lehet az oka.

az Assembly nem tudott az 5 közé kerülni és ennek mi lehet az oka

Az, hogy kóklerek írták az assembly kódot, és szégyen, ha valami magas szintről optimalizálva jobb lesz, mint natív assembly-ben írva. Persze, ha az a feladat, hogy írj meg egy böngészőt assembly-ben, akkor nyilván elmegy a maradék életkedve is az embernek. Nyilván assembly-t nem ott kell használni, ahova nem való. MCU-ra meg lehetőleg ne C++-ban meg Java-ban vagy Pythonban írjanak kódot. Még akkor sem, ha tudom, hogy nagyobb MCU-kra simán írnak C++-ban.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Miután az assembly a gépi kód ember számára érthető, mnemonikos alakja, bátran kimondhatjuk, hogy azok a nyelvek, amelyek megnyerték a sebesség versenyt, assembly kódot generáltak, azaz mindenképp az assembly nyert. Meg kellene végre érteni, hogy amit nem lehet megírni assembly-ben, azt nem lehet megírni. Valakinek talán az aláírása volt itt, és helytálló.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A kérdés az hogy az ember értelmes időn belül tud-e olyan minőségű assembly kódot írni, mint amit egy fordító csinál. Mert ha azt mondjuk, hogy bizonyos komplexitás alatt mondjuk évek alatt csinálsz olyan kódot, amit egy magasabb szintű nyelvet használó ember 1 hónap alatt megír, akkor látható, hogy semmi értelme nincs az egésznek: amire elkészülsz a nagy művel, már régen elavult.

OK, de nem PC-re kell grafikus alkalmazást írni assembly-ben, hanem 8 bites MCU-ra kerékpár lámpát például. Egy olyan MCU-ra, amelyben van néhány tíz byte RAM, két mélységű, jobb esetben nyolc mélységű stack, amely csak visszatérési címet tud tárolni, adatot nem, elég bajos magas szintű nyelven kódot írni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Köszi! Most nem tudok videózni, de meg fogom nézni, kiváncsi vagyok.

Érdekes egyébként, hogy amikor egyetemre jártam, akkor óriási hájpja volt a Javának, illetve az XML-nek. Emlékszem, hogy mondták, hogy a Javának mennyire kicsi az overheadje, és az ugye ordó konstans, ha viszont hatékony adatszerkezeteket használunk, akkor pikk-pakk gyorsabb lesz, vagy nagyjából ugyanolyan gyors, de gyorsabban lehet elkészülni vele és megéri. Ez szerintem nagyjából bejött, de például a GraalVM, ami Ahead of Time fordít, az csak az utóbbi években lett mainstream. Meg a bármikor jövő GC is megmaradó probléma, illetve, hogy egy jókora infrastruktúra kell mire egyáltalán elindul a program.

A szoftverfejlesztés egyik csapdája a bonyolultság, az elszálló fejlesztési idő, és tényleg az van, hogy amivel a legjobban kezelhetővé válik ez a probléma, az a legjobb eszköz. Én például ezért hiszek a statikusan típusos nyelvekben, szerintem ha már nem tudjuk fejben tartani, hogy mit hogy hívnak pontosan, akkor rémálommá válik a típus nélküli fejlesztés. Illetve egy rakás dolgot tesztekkel kell biztosítani, amit a típusosság automatikusan ad. A Javát a mai napig jó választásnak érzem ha nincsen semmilyen specifikus igény (pl real time, bare metal, stb) ami miatt nem jó. (Ha jól emlékszem te a JVM-re épülő modernebb dolgokat is használod, sajnos azokkal nincs tapasztalatom.)

Vagy mondták például annó, hogy ha tömöríted, akkor az XML nem lesz nagyobb mint a bináris ábrázolás és nem is éri meg binárisozni. Na, olyan már volt a praxisomban, hogy egy XML helyett binárisat csináltunk, mert meg lehetett spórolni vele vagy 10 másodpercet és ott akkor ez már számított. A feldolgozás ideje nagyon nem kevés, és sok helyen ez igenis számít. Érdekes egyébként, hogy az általam ismert Java API-k mind új string objektumot gyártanak minden tagből, ami jókora overheaddé válik egy bizonyos méret felett. Ugye az UTF parszolás is hatalmas overhead, pedig ha mondjuk számok vannak az XML-ben, akkor teljesen felesleges volna objektíve, ASCII-ben is lehetne csinálni mindent. Szerintem ilyen no-copy, no instantiation trükkökkel jócskán lehetne a Java XML implementációkon javítani, de ugye akkor teljesen új API-t kellene létrehozni. (El tudom képzelni, hogy ma már van ilyen, nem vagyok naprakész, ha valaki ismeri linkelje!) Szóval az XML szerintem nem hozta azt amit ígértek, nem elég hatékony ahhoz, hogy mindenhol ez legyen a adatcsere formátum. Nem véletlenül burjánzanak a protobuff-jellegű megoldások. Méret prefix, bináris ábrázolás és RAM olvasás sebességgel lehet parszolni! Nagyon nem mindegy! De ahol nincs komoly teljesítmény igény, ott teljesen jó az XML/JSON is, és tényleg jó, hogy ránézésre érthető.

Szerk.: megnéztem, tényleg jó. Még egyszer köszi! Szerk2.: A Zig hihetetlen mértékben nyert a videó szerint. Belepörgettem a kommentekbe, és sokan mérési módszertani hibára gyanakszanak. Szóval ezt ki kellene rendesen elemezni, hogy mi is történt valójában. Számomra meglepetés, hogy a Rust is lenyomta a C-t, de az olyan hihetőbb mértékben, hogy az validnak tűnhet elsőre.

Nyilván ez egy konkrét feladat, ami nem bizonyít semmit.

Megnéztem a méréseket és nem is értem, hogy miért szerepel a 2023. áprilisi videóban ez, hiszen 2021 októbertől kezdve, ahány mérést megnéztem, mindenhol toronymagasan a CommonLisp nyert, a Zig olyan 4.-6. között van. Megelőzi a C++, D, Rust és a C is általában.

A CommonLisp megoldásai ráadásul (már?) nincsenek is a github repóban.

Ha a Bits per prime -ot >1-re veszem, akkor ott a Zig az első, jelentsen ez bármit is ;-)

Ui.: megnéztem a Zig megoldásait, egyikben sem látok olyat, hogy fordítási időben számolná a prímeket.

Zab, nem azt mondom, hogy nincs olyan eset, amikor pont ez kell. Én is írtam (baromi rég) ilyen feltételekre programot. Assembly-t használtam.

De azt mondom, hogy ez egy speciális eset, ennek alapján nem lehet azt kijelenteni, hogy az assembly a legjobb. OK, erre a célra, ebben az esetben az volt a legjobb. Más esetben, más célra meg valami más lesz a legjobb.

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

Ne haragudj, de milyen elfogult értékelési szempont az

Semennyire sem elfogult.

hogy mekkora a lefordított program

A program méretét a hardver korlátozza, nem én. Tessék a BIOS fejlesztőinél reklamálni!

és hány kulcsszó használatával készült el?

Látszik, hogy nem értesz a gyakorlati programozáshoz. Van fogalmad róla, mekkora szopás, amikor egy nyelv kulcsszavai fordítóról fordítóra és verzióról verzióra változnak?

A való életben szerinted a programozási feladatok kb. mekkora részében szempont ez

Ahol a hosszútávú karbantarthatóság is szempont, ott 100%.

fogalmam sincs, hogy hogyan kellene a video memóriába írni

Sokat segítene, ha megtanulnál olvasni és menne a magyar nyelvű szövegértés. A kiírásban pontosan le lett írva.

És pont ezért váltottam később C/C++-ról Pythonra.

Próbálj meg beadni egy Python-os megoldást! Ha csak megpróbálnád, egyből leesne, miért beszélsz hülyeségeket.
Ja, és módosítás nélkül működjön 1-es, 2-es és 3-as Pythonnal is, ha már a nyelv kulcsszavai szerinted nem is számítanak!

Dehogy adok be megoldást! Kb. 20 éve nem nyúltam Python-hoz (se). A kiírásban szereplő hardver környezettel semmi tapasztalatom nincs, és számos jobb módon el tudom tölteni a szabadidőmet, mint olvasgatással, hogy megtanuljam, hogyan lehet kiírni valamit PC-n a képernyőre egy olyan módban, amit sohasem tervezek használni a jövőben.

Ügyes, hogy a kérdéseket / észrevételeket egyszerűen figyelmen kívül hagyod.

> hogy mekkora a lefordított program

A program méretét a hardver korlátozza, nem én. Tessék a BIOS fejlesztőinél reklamálni!

Elhiszem, hogy van olyan hardver környezet, amiben ezek a korlátok adottak. Még azt is elhiszem, így láttatlanban, hogy ebben a hardver környezetben, erre a feladatra a C a legjobb nyelv.

De ebből nem következik, hogy a C a legjobb nyelv mindenre. Helyből, nincs olyan, hogy mindenre legjobb nyelv.

Ahol a hosszútávú karbantarthatóság is szempont, ott 100%.

Nem ez a tapasztalatom.

A lefordított bináris mérete hol számít a hosszútávú karbantarthatóságban?

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

De, használod, bootloaderek így töltődnek be. Lehet te nem fejlesztesz ilyet, de nem árt tisztában lenni a természetével, ha pl. bootolási problémát kell helyreállítanod. Illetve aki ilyet fejleszt, annak is fontos.

Azt meg senki nem állította, hogy a C a legjobb, csak azt, hogy nem kell kidobni feltétlen a szemétre, ahogy azt a rust-osok állítják. Egyébként a C-ben sincs semmi szuperos, meg világmegváltás, lényegében egy architektúrafüggetlen macroassembly, ahol nem kell lemenned opcode-okig, regiszterekig, memóriacímekig, hanem tudsz helyette absztraktabb utasításokat, struktúrákat, mutatókat használni. Ilyen low level, rendszer-, egyszerű CLI programozásra mai napig használható, nem fog elavulni soha. Hiába állítják be úgy. Eleve a Linux kernel, BSD-k kódjának a megléte rá a bizonyíték, hogy mai napig működik, aktívan fejlesztenek benne modern projekteket, és hiába nem memsafe, tudják kezelni, mert ha annyira használhatatlan lenne, mint azt a hype állítja, akkor emiatt mert C-ben van írva, már az összes ilyen rendszert felnyomták volna, közben meg ez nem történet meg. Igen, elvétve vannak ilyen bufferoverflow támadások egy-egy rendszermodulban, de ahogy kiadják rá a CVE-t, általában órákon belül foltozzák.

Persze, lehet Rust-ban is írni, mindenkinek a saját projektjénél kell eldöntenie miben írja, milyen korlátokat vesz figyelembe. Kezdőknél szempont lehet, hogy a Rust újabb, ha még a C-t nem tudják, akkor nem fogja megzavarni az első nyelv tanulását, mindjárt egy modernebben tanulnak meg, azzal sincs baj. Viszont cserében a C hagyományosabb, ezer könyv, millió lib elérhető rá, jól szabványosított, minden architektúrára rengeteg implementációja létezik, a bloatabbaktól a minimalistáig, sok példakódból, tanfolyásból, anyagból lehet meríteni hozzá.

A C egyszerűbb viszont sok esetben. Pl. ha retró platformon akarod fordítani, mondjuk egy Amigán vagy egy muzeális PDP 11-en is lehet C-s kódot fordítani, pl. egyszerű CLI programokat simán. Rust-ban próbálj forgatni valamit ilyen gépen. Vagy pl. apró mikrokontrollereknél, pár MB RAM, épp csak akkora kódokat töltenek fel rá, hogy néhány tüskét vezéreljen vagy 1-2 ledet villogtasson, erre overkill lenne 13 gigás kódbázisú Rust fordítóban percekig cargo-zni a függőségeket, libeket, hogy kapj egy akkora binárist, amit már lehet fel sem tudsz arra a kis szutyokra tölteni. Mert oké, nem safe, de most ilyen felhasználási körökben mit adna hozzá a memsafety? Biztos, mert valaki ezt fogja meghekkelni, hogy egy Amigán tárolt kormánytitkokat beszerezze, meg a mikrokontrolleren vadul villogjon egy nem szándékolt 3. led is, éljünk veszélyesen.

Persze a Rust is fejlődik, már van pl. MS-DOS és m68k portja, csak minek. Ezekre ki fejleszt benne? Maximum mutatványozásra meg szellemi maszturbálásra jók, de nincs életszerűségük.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

A Rust m68k port legutóbb amikor néztem még ott tartott, hogy át akarták hekkelni miatta az évtizedes Linux-68k ABI-t a Debian Port maintainerek, mivel nem tudott valami alignment megszorítást, ami az ABI-nak kellett. Azt hiszem alapból feltételezte, hogy 32 bites procin 32 bit (4 byte) alignment lesz legalább, miközben 68k-n 2 byte (16 bit) az ABI által előírt alignment. És egy rakás upstream Rust kóddal is hasonló dolgok voltak.

Végül szerencsére nem lett belőle semmi tudtommal, hanem még várnak, amíg a fordító meg az ököszisztéma érik egy kicsit... :) Nem is főleg a Linux miatt, hanem mert pl. sok sikert a AmigaOS-t, Atari TOS-t/Mintet, régi MacOS-t támogatni, amíg ezek egy modern Linux retró portján sem mennek (ami mindig az egyszerűbb feladat).

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Vagy pl. apró mikrokontrollereknél, pár MB RAM

Vagy néhántszor 10 bájt...

Memsafe-ről jut már megint eszembe, amikor nemrég egy jól képzett fiatalemberrel dolgoztam együtt és bájt szintű protokollt fejlesztettünk:

- Bocsi, tudod mi az a hexdump?

- Ööö...hallotam már a kifejezést.

Persz az open() kompatibilis glassfish függvényt is én kerestem ki neki... :-D

A C pedig azért nem fog eltűnni, mert az az egyetlen hordozható nyelv. De megsúgom, hogy az arch közeli programokat nem azok fogják hordozni, akik "hallották már". ;)

Érdemes lenne a Zig-re is ránézned. 

Miközben jóval "biztonságosabban" lehet benne az alkalmazásokat megírni, aközben a fent említett Rust-os problémák sincsenek. Tudsz pár száz byte-os alkalmazást is írni akár, ismer alapból 60+ architektúrát, 30+ OS-t, 40+ ABI-t. Keresztbe tud fordítani, tehát pl. akár egy x86_64-es linux architektúrán a kódot le tudod fordítani m68k macos-re is vagy 32 bites windowsra.

apró mikrokontrollereknél, pár MB RAM

Még nagyobb, 32 bites mikrokontrollerekben sincs sokszor 1 MiB RAM. A mikrokontrollerekben jellemzően néhány tíz byte és néhány kiB közötti SRAM van. Most egy 8 bitesek között már elég nagy MCU-t használok, 4 kiB RAM-ja van és 64 kiB flash-sel rendelkezik, ami 32 kword, mert az utasítások word-ösek jellemzően. Erre már viszonylag kényelmesen lehet C-ben programozni. Jó, rekurzív hívás ne nagyon legyen benne, mert 128 mélységű a stack.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

nem kell kidobni feltétlen a szemétre, ahogy azt a rust-osok állítják

Ezzel bármiféle programozási versenyfeladat nélkül egyet tudok érteni.

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

Ügyes, hogy a kérdéseket / észrevételeket egyszerűen figyelmen kívül hagyod.

Mindegyikre válaszoltam, tételesen, veled ellentétben.

Elhiszem, hogy van olyan hardver környezet

Szó sincs erről. Arról van szó, hogy a C egy rendszerprogramozási nyelv, amiben játszi könnyedséggel oldhatók meg az ilyen feladatok, így minimum elvárás, hogy minden "C gyilkos" nyelv is tudja ezeket.

De ebből nem következik, hogy a C a legjobb nyelv mindenre.

Soha senki nem mondott ilyent. Arról volt szó, hogy Rust-os vérpistikék szerint ki kell dobni a C-t, és ez a verseny ékesen bebizonyította, hogy hát nagyon nem.

Helyből, nincs olyan, hogy mindenre legjobb nyelv.

Az ilyen "legjobb nyelv valamire" egyáltalán nem egy egzakt, objektív eldöntendő kérdés valójában, csak flamelés indításra való (a PHP vagy a Java a legjobb webfejsztésre?).
Az, hogy majd egy nyelv fícsörei helyettesítik a programozói tudást, alapból hibás nézet. Marad az, hogy lustaságból / tudatlanságból / toolkészletkényszerből választasz egy adott nyelvet, nem máté'. Véletlenül sem "jóság" alapján.

Nem ez a tapasztalatom.

A micsodád? Pont most mondtad, hogy 20 éve még csak nem is programoztál. Nincs is semmiféle tapasztalatod.

A lefordított bináris mérete hol számít a hosszútávú karbantarthatóságban?

Valójában mindenhol, még ha a tudatlan vérpistikék és/vagy lusta programozók az ellenkezőjét is próbálják elhitetni.

Tegyük fel, ha van két program, ami ugyanazt csinálja, de az egyik 300K, a másik 400M, akkor
- melyiket könnyebb terjeszteni,
- melyik indul el gyorsabban és
- melyikben lehet több bug, backdoor, malware, stb.?
Igazából nem is létezik olyan végfelhasználói szempont, amiben ne a kissebb bináris nyerne.

Egyszer volt hol nem volt, volt egyszer egy program amit ket neylveben irtak meg. Nem sok sor volt egyik sem, se a C se a Java. A C-ben a 10 sorban 7 oltari hiba volt, a Java-ban ha akartak volna se tudtak volna azokat a hibakat belerakni a. A C kurva kicsi volt, a java hozza kepest bohom nagy (par byte). A C gyrosabban indult majd gyorsan memory leak-elt es meg is doglott. A "bohom" java par ezredmasodperccel lasabban indult, de futott es nem halt meg. A c-t kicsit lassabban irtak meg, a Java-t gyorsabban.

Soval volt egy apro es gyorsan indulo leakelo C es egy picit nagyobb, kicsit lasabban indulo atomstabol Java implementacio. 

"Igazából nem is létezik olyan végfelhasználói szempont, amiben ne a kissebb bináris nyerne." ...aham :D

A 300K vs. 400M kerdesekre:

* Ha nem tudod mind a kettot ugyanolyan konnyen terjeszteni, akkor ott nagy bajok vannak

* Ha az szamit melyik indul el gyorsabban, akkor ott valoszinuleg az az eyetlen szempont hogy meyik indul el gyorsabban (nem szamit a stabilitas, es hogy mit is csinal, itt mar irtak paran hogy a nagyszeru C programot atteve pyspark-ra maris 100-szorosara gorsult a dataprocesszing, mikozben korulbelul leszartak milyen gyrosan indul el, mert nem az volt a business szempont, hanem hogy milyen gyorsan vegez az adatokkal egy distributed computing eseten)

* A program merete es a hibak mennyisege nem all korrelacioban (lad a fenti peldat, de ha kell adok neked egy python programot, ami csak kb. 80 sor es szinte mindegy egyes soraba bele lehet kotni sot architekturalisan is szar, a javitott verzioja dupla annyi sor, megsem tartalmaz egyetlen hibat sem, szoval errol ennyit)

 

Persze tudom hogy kurvara feleslegesen tepem a pofam. Aki csak egy kulcslyukon keresztul latja a vilagot, annak az is hatalmas es meg tudja magat gyozni hogy csak annyi is a vilag :D

Soval volt egy apro es gyorsan indulo leakelo C

Beképzelsz magadnak baromságokat. Nem is sóval van ízesítve, és valgrind mondja All heap blocks were freed -- no leaks are possible. Ne hazudj, nem is leakel.

es egy picit nagyobb

A különbség több, mint tízezerszeres! Teccik érteni? 10 000-szeres. Ha valaki 100 Ft helyett 1 milliót kér tőled, arra is azt mondod, okés, ez csak "picit" több?

Ha nem tudod mind a kettot ugyanolyan konnyen terjeszteni, akkor ott nagy bajok vannak

Na látod ebben egyetértünk, a 400M-esnek még egy valag függősége is van pluszban, így összehasonlíthatatlanul problémásabb a terjesztése.

akkor ott valoszinuleg az az eyetlen szempont hogy meyik indul el gyorsabban

Már megint feltételezel baromságokat, aztán meg persze nem túl meglepő módon hibás következtetésekre jutsz a fals premisszáidból.

Persze tudom hogy kurvara feleslegesen tepem a pofam.

Hát az biztos.

Aki csak egy kulcslyukon keresztul latja a vilagot

Legalább a kulcsot kivennéd belőle, hogy át is láss valamennyire... De nem, te csak hibásan feltételezel mindenfélét és téped a pofád. (A Te szavaid, nem az enyém.)

ejj ocsem latszik hogy csak a kicsi vilagodban elsz, ki a tokom mondta hogy a te programodrolvan szo

Ja, még be is vallod, hogy csak képzelődtél? LOL.

Egyszer volt hol nem volt, volt egyszer egy program

en elmeseltem egy igaz tortenetet

Annyira jót mulatok azon, ahogy hülyét csinálsz magadból... Kérlek folytasd! Csak várj előbb egy kicsit, mert elfogyott a popcornom, hozok még!

Most komolyan, itt egy csávó, aki semmit nem tett még le az asztalra, saját bevallása szerint sem ért hozzá, 20 éve nem is programozott, folyton önellentmondásokba keveredik, és még csak helyesen magyarul írni sem tud.
Ha valaki mégis komolyan venné, szvsz annak úgy is kell, megérdemli, az biza' magára vessen ha pórul jár! :-D :-D :-D

ertem en hogy isten komplekszusban szenvedsz es azt hiszed minden is rolad szol, de ott bukik meg az egesz amikor kaparsz mint diszno a jegen, hogy bebizonyitsd magadnak hogy mindnki mas hulye. :D

Megegyszer (lassan irom, hatha felfogod te is);

* A tortenet igaz volt, nem kitalalt csak Te azonnal belehelyezted az icipici vilagodba es azt mondtad, hogy hazudok mert nem is ugy volt az a tortenet aminek Te nem is voltal a reszese. (na de hogyan lehetseges az mikor te vagy az isten es minden rolad szol...ejj ejj, na itt csinaltal eloszor magadbol hulyet kiscsiko)

* Letenni valamit az asztalra nem annyit jelent hogy irok egy szaros C programot, meg ha a te vilagodban ezt is jelenti. Valoszinuleg a legtobb orvos es pek sem ir C programot de megis tobbet ernek mint te (a tobbiekrol, mint architect, dvops, uzemelteto, tesztelo, vagy csak egy technikus a gepteremben). Persze a valo vilagban nem a tiedben, ahol te vagy a mindenhato aki mindent is tud mindenrol es hatarozza meg az ertekeket. :D 

Persze foloslegesen irom le ezeket, mert a fejedben mindent es mindenkit legyozol a tokeletessegeddel. Szanalmas lehetnel, ha nem lennel kozben vegtelenul nevetseges :D

Szoarkozzunk egyutt. Te a kis icipici vilagodban mi meg a valosagban :D

Nem ez a tapasztalatom.

A micsodád? Pont most mondtad, hogy 20 éve még csak nem is programoztál. Nincs is semmiféle tapasztalatod.

Attól, hogy nem én írtam a programot, még dolgoztam számos szoftver fejlesztési projektben. Nem egyet évtizedeken át kellett utána karbantartani és üzemeltetni. Innen származik a tapasztalat.

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

Nem, nem, ha nem vagy programozo akkor semmit sem ersz. Ha meg meg programozo is vagy, akkor sem ersz semmit ha nem vagy C progranozo. Akkor is csak kicsivel vagy kevesbbe semmi.

Itt meg is mondtak mar nekem, hogy "valójában a szánalmas kis faszaid nem tartanak semmit sem össze az IT világában" (teszterek, infrastruktura mernokok, hardware tervezok, devops-ok, uzemeltetok, architektek), csakis a C programozok miatt mukodik az IT vilagban minden IS. :D

Nem, nem, ha nem vagy programozo akkor semmit sem ersz.

LOL, ilyent írni egy kifejezetten programozásról szóló topikba, amikor programozási nyelvekről szól a disputa...
Öcsém, Te aztán tényleg feketöves vagy abban, hogy hülyét csinálj magadból! :-D :-D :-D

Így is van!

Golgota írta:

Az en szintemen a sok kis szanalmas fasz tartja ossze a te kis ITs vilagodat

https://hup.hu/comment/3036421#comment-3036421

Fantasztikus, hogy mindig azt hiszem, ennél lejjebb már nincs, de neked újra és újra sikerül még nagyobb hülyét csinálnod magaból! :-D Tényleg fantasztikus teljesítmény!
Na, én léptem, ennyi trolletetés elég volt nekem, jól kiröhögtem magam.

Érkezett Zig és Swift megoldás is!

Lassan tényleg az összes nyelven elkészült legalább egy megoldás! Kezd hasznosabb lenni a repó, mint esedetileg sejtettem, nagyon jó kis összehasonlítási alap lesz belőle!

Én sem gondoltam volna, de számomra is nagyon hasznos lett végül ez a fórum és feladat.

Emiatt ismertem meg a Zig-et és eléggé meg is kedveltem. Ismerkedés gyanánt a tavalyi advent of code-ból megcsináltam 9 feladatot, megnéztem pár videót, arról nem is beszélve mennyire nagyon hasznos és informatív a dokumentációja.

Ennek a nyelvnek is az az alapvetése, hogy minél stabilabb kódot lehessen vele készíteni, de mindezt úgy, hogy minden eszközt meghagy az ember kezében. Kézi memória foglalás, felszabadítás, de a felszabadítást már jelezhetjük egyből a foglalás után. Teljesen egyéni memóriafoglalásokat is készíthetünk, van pár előre elkészített is, illetve használhatjuk a jó öreg c-s malloc-ot is ;-).
A Rust mintájára még egy zorrow nevű library-val borrow alapú allokációt is használhatunk.

A biztonság inkább onnan jön, hogy explicit a hibakezelés, minden hibát a függvény szignatúrában is jelezni kell, illetve kezelni is kell azonnal, de azt lehet kényelmesen tovább adni is, de azt is explicit meg kell adni.
A másik ilyen a null kezelés. Gyakorlatilag nem lehet vele null pointer hibákat csinálni. Explicite kell jelezni, ha valami lehet null és explicite le is kell kezelni.
A beépített test mechanizmus is nagyon jól kitalált, ráadásul a memory leak-ek felderítésére is jó.
Teljesen integrálható a C, C++ programokkal, libekkel. Közvetlen a header fájlokat tudja használni.

Ami még nagyon tetszik, hogy nagyon könnyen tanulható. Minden nagyon egyszerű benne.
Jelenleg még csak a 0.12-es verziónál tart, de már így is sokan használják, főként belsős projekteknél.
Szóval még bármi lehet belőle, érdemes időnként rápillantani.
A stackoverflow developer survey-n a 4. legkedveltebb nyelv, illetve a legjobban fizető ;-)

Egy-két dolgot többféleképpen is megcsináltam benne, amik nagyon érdekes tapasztalatokat nyújtottak. Majd később ezekről is írok.

Szerkesztve: 2024. 04. 01., h – 13:25

És.... Nim megoldás is érkezett!

Lassan tényleg ott tartunk, hogy nagyon erősen kell gondolkodnom, melyik nyelv maradhatott még ki :-) Aminek nagyon örülök! Még egy hét van a határidőből, ha esetleg valaki kedvet kapna hozzá.

Már azt hittem, nem érkezik már több megoldás, amikor is egy újabb igazi ínyencfalatot kaptunk, Haskell megoldást! Igaz, nem használja az interfészt (fix címes linker szkript), de sebaj, akkor is hatalmas gratula a készítőnek!

Ma éjfélkor jár le a határidő, addig még lehet megoldásokat beküldeni.

Szerkesztve: 2024. 04. 09., k – 18:41

EREDMÉNYHIRDETÉS

Először is hadd köszönjem meg mindenkinek, aki vette a fáradságot és küldött be megoldást! Sokkal több érkezett be, mint vártam, és az külön örömömre szolgál, hogy nem HUP-os kollégáktól is érkeztek megoldások.

A teljes lista nyelvekre lebontva, ábécé sorrendben (zárójelben a beadott megoldások darabszáma):
- Assembly (1, referencia)
- C (3)
- C# (1)
- Go (1)
- Haskell (2)
- Nim (1)
- Pascal (1)
- Rust (2)
- Swift (1)
- Zig (1)

Meg kell, hogy mondjam, eléggé impozáns a lista, ezért a repót archiváltam és eltettem az utókornak, mert egy ilyen remek mintatár nem igazán van még. Ha nem felejtem el (majd emlékeztessetek), akkor egy év múlva szeretném újra elővenni, és megnézni, hogy az akkori legfrissebb fordítókkal mely források fordulnak majd le módosítás nélkül.

És akkor az eredményhirdetés: a kiírás szerinti feltételek alapján a nyertes a Pascal lenne, de sajnos diszkvalifikálnunk kell, mert róla már konkrétan tudjuk, hogy nem volt képes leváltani a C-t. Így a második befutóé az érdem.

Ez pedig nem más, mint Zig. Kis bináris, szép olvasható kód, tömör leírás (75 sor egyetlen fájlban), egyetlen speciális kulcsszó csupán (callconv(.C)), egyébként csak natív nyelvkészlet lett felhasználva a megoldáshoz. Ha valaha is elévül a C, akkor - a kiírás feltételei és a beérkezett megoldások alapján - ez a leváltására legesélyesebb nyelv (*) (**).

(*) - fontosnak tartottam kiemelni, hogy a kiírás feltételei alapján, mivel minden szempont nem lett figyelembevéve, nem is lehetett volna, hiszen eléggé eltérőek a nyelvek. Szerény véleményem szerint a valóságban mégsem lesz a Zig befutó, de olyan okok miatt, amelyeket ez a verseny nem tudott már vizsgálni (memóriakezelés vagy architektúralefedettség például).
(**) - nem volt érkezésem Zig fordítót telepíteni és letesztelni, ezért ha esetleg kiderülne róla, hogy áprilisi tréfa volt csupán, mivel április 1.-én lett beadva, akkor a nyertes automatikusan a Nim (szintén szép olvasható kód, de eggyel több speciális kulcsszó (cdecl., .exportc) és a kigenerált bináris is kevésbé optimális, 994 bájt vs. 14704 bájt).

Mégegyszer nagyon köszönöm az összes résztvevőnek a megoldásaikat! Roppant tanulságos repó született, ami remélem hasznára válik majd pár embernek a jövőben!

Gratulálok!

Bár az is igaz, hogy ezt a kiírást már az elején sem értettem. Először azt hittem ez egy Rust vs C, C++ hitvitából indult. De nem mert te csak a C-ről beszélsz. 

Ezt tőled idézem:

csak a használhatósága tartja fenn a népszerűségét és NAGYON kevés a C programozó a többi nyelv programozószámához képest.

=> Ha a C csak egy rétegnyelv, akkor a leváltást mint fogalmat nem tudom rá értelmezni.

Számomra csak az nem derült ki a kiírásból: Hogy kik, milyen területen, miért, hogyan és mire cserélnék le a C-t? Vagy másként fogalmazva mi fel ez az egész.

A C győzelmét persze borítékoltam, csak ebben a formában nem bizonyít semmit.  

Először azt hittem ez egy Rust vs C, C++ hitvitából indult.

Onnan indult. Az eredeti szándék az volt, hogy rámutasson, a Rust valójában a gyakorlatban nem is memóriabiztonságos nyelv, de aztán jóval túlnőtt a verseny ezen (de persze ezt is ékesen bebizonyította, lásd mennyien sírtak az "unsafe"-ért, mert annélkül egyszerűen nem tudták volna megoldani).

Ha a C csak egy rétegnyelv, akkor a leváltást mint fogalmat nem tudom rá értelmezni.

Egyrészről nem is rétegnyelv (rendszerprogramozától kezde embedded-en át alkalmazásprogramozásig mindenre használják és tényleg mindenhol ott van), másrészről meg még mindig dögivel indulnak benne új projektek, ezért még ha értelmezni is tudnád, akkor sincs szó semmiféle leváltásáról.

Hogy kik, milyen területen, miért, hogyan és mire cserélnék le a C-t?

Ha nem érted ezt az jó, akkor ez a verseny pontosan azt mutatta meg, amit meg akart mutatni: eleve értelmetlen ez, és hülyeségeket hord össze, aki a C lecsérléséről beszél. Q.E.D.

A Zig-es megoldás nem áprilisi tréfa ;-)

Egyébként nézhetjük úgy is, hogy két vagy három megoldást is adtam Zig-ben.

1. Elf megoldás 
2. Exe megoldás
3. noptr megoldás

Az 1. és 2. az ténylegesen egy megoldás fizikailag is, de két formátumra (architektúrára) van lefordítva.
A 3. pedig a noptr-es megoldás, ami kicsit csalás, mert a linkelésnél adjuk meg a pointereket.

Ami érdekesebb, hogy kétféleképpen is megadtam az idt tábla töltését. Az egyik a C-s, bitvadász megoldás:

idt[32 * 2] = @shlExact(@intFromPtr(&isrHandler) & 0xffffffffffff0000, 32) | 0x8E0000200000 | (@intFromPtr(&isrHandler) & 0xffff);

Ez egyetlen sor, de hatalmas hibalehetőségekkel.

A másik terjedelmes, de sokkal biztonságosabb és (szerintem) olvashatóbb megoldás:

const interrupt_descriptor_64_t = packed struct {
    base_low: u16,
    selector: u16,
    ist: u8,
    flags: u8,
    base_mid: u16,
    base_high: u32,
    reserved: u32,
};

const idtType = [48]interrupt_descriptor_64_t;

load_idt: *const fn (idt_address: *const idtType, idt_size_in_bytes: u16) callconv(.C) void,

...

    const isrh = packed union {
        addr: packed struct {
            low: u16,
            mid: u16,
            high: u32,
        },
        ptr: usize,
    }{ .ptr = @intFromPtr(&isrHandler) };


    idt[32] = interrupt_descriptor_64_t{
        .base_low = isrh.addr.low,
        .selector = 32,
        .ist = 0,
        .flags = 0x8e,
        .base_mid = isrh.addr.mid,
        .base_high = isrh.addr.high,
        .reserved = 0,
    };

    systab.load_idt(&idt, sizeOfIdt);

Természetesen emiatt is lett 75 soros a megoldás, szemben a noptr-es 38 sorral.
A lefordított binárisban nincs nagyon különbség méretben. ;-)

Egy másik érdekesség, a számláló kiírása.

Itt is két megoldást adtam:

1. Alacsony szintű, kézi megoldás

    if (counter == 100) {
        counter = 0;
        if (vga[6] != '9') vga[6] += 1 else {
            vga[6] = '0';
            if (vga[4] != '9') vga[4] += 1 else {
                vga[4] = '0';
                if (vga[2] != '9') vga[2] += 1 else {
                    vga[2] = '0';
                    if (vga[0] != '9') vga[0] += 1;
                }
            }
        }
    }

2. Kicsit magasabb szintű megoldás

    if (counter == 100) {
        counter = 0;
        for (0..4) |i| {
            if (vga[(3 - i) * 2] != '9') {
                vga[(3 - i) * 2] += 1;
                break;
            }
            vga[(3 - i) * 2] = '0';
        }
    }

Utóbbinak az az érdekessége, hogy ha méretre optimalizálva fordítjuk, akkor lényegesen kisebb lesz, mint a fenti. Emiatt is tudott a noptr-es megoldás 656 byte-on elférni.

Ha pedig teljesítményre optimalizálunk, akkor kvázi ugyanazt kapjuk, mint a fenti. ;-)

A Zig-es megoldás nem áprilisi tréfa ;-)

Én sem néztem annak, de a kisördög sosem alszik! Örülök, ha nem az.

Egyébként nézhetjük úgy is, hogy két vagy három megoldást is adtam Zig-ben.

1. Elf megoldás
2. Exe megoldás
3. noptr megoldás

Minden nyelvnél ugyanúgy számoltam, ha az Elf és az Exe kimenet forrása ugyanaz, azt egynek vettem. A noptr a forrásban is eltér, emiatt az külön megoldásnak minősül, így jött ki a kettő a végén.

Ez egyetlen sor, de hatalmas hibalehetőségekkel.

Ha a bemenet mindkét esetben pont ugyanaz és érvényes (az előfeltétel mindkettőnél ugyanaz és teljesül), akkor nem szabadna, hogy e két megoldás eltérő hibalehetőséggel rendelkezzen. Ha igaz, amit írsz, akkor az pont egy olyan dolog, amire egy nyelv hosszú távú fenntarthatóságával akartam utalni.

Oppsz, most látom, tényleg elírtam, Zig-nél is két megoldás kéne szerepeljen, de már nem tudom javítani a posztot.

Ha a bemenet mindkét esetben pont ugyanaz és érvényes (az előfeltétel mindkettőnél ugyanaz és teljesül), akkor nem szabadna, hogy e két megoldás eltérő hibalehetőséggel rendelkezzen.

Az elsőnél bárhová mutathat az a pointer, amit kap a load_idt függvény. A másodiknál csak a megadott típusúra mutathat, ami 48 elemű tömb, aminek a felépítése is szigorúan meghatározott. Ott nem téveszthetem el könnyen, hogy hová kerül a 0x8E flag, vagy hová kerülnek a megszakítás függvény alsó, közép 16 bitje illetve a felső 32 bitje. Ilyenekre gondoltam.

Oppsz, most látom, tényleg elírtam, Zig-nél is két megoldás kéne szerepeljen, de már nem tudom javítani a posztot.

Nem nagyon érdekes ez. Szóval, jó így! ;-)

Az elsőnél bárhová mutathat az a pointer, amit kap a load_idt függvény.

Az előfeltétel akkor is ugyanaz mind a kettőnél, és a "bemenet minkét esetben érvényes" kitétel alapján nem akárhova mutat, hanem mindkét esetben érvényes IDT-re. Ekkor nem látom be, hogy a kigenerált kód miért kéne eltérjen, és hogy a futás időben miért is lenne más a hibalehetőségük.

Amit írsz, az csak fordítási időre szorítkozik, aminek nincs köze a kigenerált kódhoz.

Kicsit off: már régóta hangoztatom, hogy nem a programozó kezét kell megkötni és lelassítani a fordítást, hanem arra kell fókuszálni, hogy minnél hatékonyabb legyen a kigenerált kód. Ez szembemegy a mainstream nézetekkel, de az érvem egyszerű: míg a fordítási idő drága és jellemzően csak a projekt elején szerepel, addig a futási idő hosszú, jó esetben egy-egy megírt programot évekig is használhat számtalan olcsó munkaerő. Konkrét (szándékosan idióta) példa: a passziánszt megírni kb. 1 szakember 1 hetes munkája volt, addig több évtizede (!) használja a világon mindenfelé sok-sok-sok titkárnő.

Ez persze egy ilyen kicsi projektnél nem szembetűnő, de egy nagyobb, többemberes projektnél a hosszú fordítási idő már konkrétan anyagi veszteségben is mérhető, a kevésbé optimális kód pedig a számtalan végfelhasználó pénztárcáját rövidíti meg hosszú-hosszú éveken át. Jobb az, ha buta a fordító de piszok gyors, mintha tele van ellenőrizéssel és emiatt lassú (ráadásul mindent úgysem tud leellenőrizni, a programozói tapasztalatot és a tesztelést sem képes kiváltani, azokra továbbra is szükség van). Ehelyett sokkal gazdaságosabb a rapid development cycle, azaz ha gyors a fordítás + tesztelés iteráció, és tapasztalatom szerint a több tesztelés jobb végeredményt is jelent egyben. Ez persze elsőre sosem látszik (mert minden projekt kicsiben kezdi), de ha megnézel egy olyan monstrumot, mint a LibreOffice pl, akkor már szignifikáns, és ne felejtsük el, a drága programozói órabért akkor is kell fizetni, ha a programozó épp matyizik, mert a fordítóra vár.

Visszatérve ehhez a versenykiíráshoz, ennél a konkrét esetnél például mindjárt a legeslegelső tesztnél egyből kibukna, ha rossz helyen lenne a 0x8E. Emiatt egyszerűen anyagilag nem éri meg lassítani a fordítást ennek ellenőrzésével.

Nem nagyon érdekes ez. Szóval, jó így! ;-)

Kösz, és mégegyszer bocs!

Az 1. és 2. az ténylegesen egy megoldás fizikailag is, de két formátumra (architektúrára) van lefordítva.

Itt még az is érdekesség, hogy tetszőleges architektúrán fordíthatunk teljesen más architektúrára. A fenti megoldást én Linuxon fordítottam a Linux-ost és a Windows-ost is, de lefordulna Windowson is a Linuxos. Illetve ez igaz a sok tucat többi architektúra és OS kombinációjára is.

Érdeklődnék, hogy akkor, az eredeti kiírás értelmében -- tekintve, hogy érkezett be csodanyelv megoldás, és nem a C nyert -- a továbbiakban hirdethetem, itt a hupon, a babzsákfotelben nevelkedett soydev fejlesztő barátaimmal egyetemben, hogy a Zig képes leváltani a C-t? Nem mintha különösebben érdekelne, valójában a sértődöttség eredeti okát sem vágom, igazából az elmúlt 10 évben főleg csak azért járok ide, mert szórakoztat a politikai flame.

Mindezektől függetlenül köszönöm a kiírást, egyrészt a Pascal-os kódot megkönnyeztem, legalább 25 évvel ezelőtti emlékeket idázett fel,  másrészt azért, mert  engem teljesen meggyőzött a Rust létjogosultságától. Ricpet rust kódját egy kicsit megpatchelve sikerült összehozzak egy 286 byte-os binárist, ami 63%-ka az assembly referenciaimplementációnak ¯\_(ツ)_/¯.

Hogy legyen érvényes része is a hozzászólásomnak, létezik a rust unsafe-nek egy sokkal kevésbé entitled kritikája is, az érdelkődőknek javaslom ezt: https://zackoverflow.dev/writing/unsafe-rust-vs-zig/

Ugyanitt: @ricpet, ha az vagy akinek tippellek, akkor helló, és jó látni, hogy a türelmed még a régi :-D

a továbbiakban hirdethetem, itt a hupon, a babzsákfotelben nevelkedett soydev fejlesztő barátaimmal egyetemben, hogy a Zig képes leváltani a C-t?

Egyértelműen nem. Csak annyit hirdethetsz ki, hogy
- ha valaha is leváltásra kerülne a C (de nem), és
- ha semmi más, csakis az itteni versenyben megfogalmazott feltételek számítanának (de nem), és
- ha a mostani 2024-es állapotot veszzük alapul,
akkor a Zig nagyobb eséllyel rúgna labdába, mint mondjuk a Rust (az majd elválik egy év múlva, hogy még működni fog-e egyáltalán, a C felől a legkissebb kétségem sincs, mivel az ANSI C szabvány utólag nem változhat, a Zig-ben, Rust-ban, stb. már egyáltalán nem vagyok biztos, a Go-ról meg konkrétan tudom, hogy már többször eltörték az utóbbi években).

igazából az elmúlt 10 évben főleg csak azért járok ide, mert szórakoztat a politikai flame.

LOL, ezen jót mulattam, köszönöm!

Ricpet rust kódját egy kicsit megpatchelve sikerült összehozzak egy 286 byte-os binárist,

Esetleg velünk is megosztanád a forrást és ezt a bizonyos binárist? Csak úgy bemondásra senki sem fog hinni neked!

Esetleg velünk is megosztanád a forrást és ezt a bizonyos binárist? Csak úgy bemondásra senki sem fog hinni neked!

Mivel saját kódot nem csináltam, máséba meg nem akarok belekontárkodni, beküldeni nem terveztem, de ha valakit érdekel, le kell cserélni a `linker.ld`-t bármelyik noptr-es megoldás alattival, kihagyva belőle a statikus bindingokat az elejéről, meg a Cargo.toml-be meg kell még egy `opt-level = "z"` a `profile.release` sectionbe. Bonyolultabb projekt esetén még egy `lto = true` is, de az itt most nem oszt, nem szoroz. Az így a fordított bináris mérete 568 byte lesz, de ahhoz, hogy fair módon össze lehessen vetni az assembly implementációval, ami nem készít sectionöket csak segmenteket, érdemes még egy elfutils-os `eu-strip --strip-sections program.elf -o stripped.elf` parancsot lefuttatni, így lesz 288 byte-os az output. A maradék pár byte-ot mindenféle hekkelésekkel lehet lefaragni, amik valójában csak rontják a kódot, pl ki lehet hagyni a high ptr inicializálást meg ilyenek.

a kiírás szerinti feltételek alapján a nyertes a Pascal lenne, de sajnos diszkvalifikálnunk kell, mert róla már konkrétan tudjuk, hogy nem volt képes leváltani a C-t

Először is jót röhögtem, mivel ugye akkor az eredeti szempontok szerint a Pascal technikailag átugrotta a komplett newschool mezőnyt, de mindenkinek egyszerűbb ha ugye ezt nem vesszük figyelembe, mert az milyen kényelmetlen lenne már... :))) Másodsorban meg rém ironikus módon kb. ez az egész attitűd az, ami miatt a Pascal sosem tudta leváltani a C-t. Ha valami egyszer megkapja az "uncool" matricát, tökmindegy mit tud technikai fronton, ha lesz rajta sapka az lesz a baj, ha nem, akkor meg az. Objektív mérce my ass.

Sebaj. 20+ éve is itt voltunk, ha lesz ilyen "contest", mi 20+ év múlva is itt leszünk. Kiváncsi leszek hány nyelv lesz a mostani próbálkozók közül az akkori listán... :)

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Ennyire mélyrehatóan nem ismerem sem a C-t, sem a Pascal-t. Nekem, mint koca "programozónak", a kódokat megnézve kb. egy polcon vannak. Nem tudom mi az amiben a C mondjuk többet ad, mint a Pascal? Vagy esetleg valamit egyszerűbb megcsinálni benne. A Pascal olyan szempontból szimpatikusabb, hogy jobban hajaz a funkcionális nyelvekre.

Eresszük rá az AI-t, és fordítsa le a Linux kernelt C-ről Pascal-ra. :-)

Kb. egy polcon vannak, valóban. Amik miatt én szeretem - típusrendszer, különösen egyes elemei (pl. tömbök, stringek, set-ek kezelése), az unit-rendszer includeok helyett, valamint a jobb átjárhatóság a magasabb szintű dolgok felé (Object Pascal/OOP), ill. pl. egy csomó minden "fejlettebb" konstrukció is használható sima procedurális stílusban - pl. Unicode stringek. Jóval kevesebb a nem definiált működés mint C-ben, és kevesebb a csapda amibe folyton bele lehet esni - pl. próbáltál már C-ben függvénynek átpasszolt tömbön (asszem, rég volt) sizeof-ot használni? Meglepő és mulatságos tud lenni. Amíg nem nagyon bonyolult projekteket írsz benne, nem kellenek Makefileok, a fordító képes felépíteni az unitok közötti függőségi fát a "főprogramból" kiindulva. Alkalmazásfejlesztéshez ezek miatt szerintem a Pascal jobb lehet. Főleg ha belekóstolunk a RAD-ba és a GUI alkalmazások világába, a Delphi még mindig elég erős, nyílt forrású/keresztplatformos megoldásnak meg ott a Free Pascalra építő Lazarus IDE. (Én nem használom, de van aki nem tud meglenni nélküle.)

Amik C-hez képest hátrányok lehetnek - nehézkesebb/jóval kevésbé fejlett makrózás, gyakorlatilag nincsenek varargs függvények (nézőpont kérdése, ez hátrány-e, alternatívák vannak rá), union struktúrák kezelése macerásabb, a világ C/C++-ban van írva, emiatt interfészelni egyes dolgokhoz problémás lehet. Kevesebb fordító van, és ezek, főleg az optimalizálás tekintetében jóval kevésbé fejlettek mint a C-s megfelelőik, emiatt az igazán teljesítményigényes algoritmusok tekintetében általában hátrányban lesz a nyelv. Kevesebb külső támogató eszköz van, a C-hez írtak egy része használható ha tudod mit csinálsz. De nem ideális. Így hirtelen.

De mégegyszer, a célom nem az volt hogy bárkit meggyőzzek a Pascalról, vagy bármiről. Én csak követtem egy nyilvános versenykiírást. Arról nem tehetek, hogy a megoldásom egyesek szerint nem a megfelelő eszközben sikerült túl jól. :P

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

C-ben függvénynek átpasszolt tömbön (asszem, rég volt) sizeof-ot használni

Itt mire gondolsz? Ha a tömb pointerét adod át, a függvényed nem tudja a tömböd méretét, külön paraméterként kell átadnod a méretét vagy az elemszámot. Illetve meg kell különböztetni a méretet az elemszámtól. Utóbbi makró szokott lenni, ami a méret és a nulladik elem méretének hányadosa. Továbbá stringeknél a sizeof és az strlen() nem azonosak még akkor sem, ha az utolsó byte-ig fel van töltve a terület a stringgel, mégpedig a lezáró nulla miatt.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ez OK, de most előástam, az van, hogy a tömbök C-ben mindig referencia szerint adódnak át, és a sizeof() egy függvényben nem a tömb méretét fogja olyankor visszaadni, hanem az alatta lévő paraméter referenciáét, valami rejtélyes, valszeg "történelmileg így alakult" ok miatt. Gondolom a varargs dolgokhoz hasznos ez, vagy valami hasonló nagyokosság... Én meg egyszer beszoptam, hogy refaktoráltam valami kódot, ami egy globális tömb változót sizeof()-olt, és átraktam paraméterbe a tömböt, hogy több példányra is meg lehessen hívni, és az összes sizeof() mágia ami a függvényben volt, atomjaira hullott. Szóval igen, hiába volt egy konstans fix méretű typedef a tömb, plusz paraméterben át kellett adni a méretét is - vagy az elemszámot... Amúgy a modern C fordítók (clang legalábbis, macOS-en) warningol erre, nagyon nagyon helyesen, de ez még "anno" volt, akkor még a régi GCC nem tette, az adott embedded platformon - és be is szoptam...

#include "stdio.h"

typedef char arr_t[1337];
arr_t arr;

void func(arr_t arr) {
  printf("%ld\n",sizeof(arr));
}

int main() {
  printf("%ld\n",sizeof(arr));
  func(arr);
  return 0;
}

Ez a kód a következő outputot adja (64bites gépen):

charlie@chainmbp-m2 arr_t % ./a.out
1337
8

A Pascal változata a kódnak ellenben konzisztens saját magával (a HUP nem tud Pascal kódot syntax highlightolni, bocs):

type
  arr_t = array[1..1337] of char;

var
  arr: arr_t;

procedure f_val(arr: arr_t);
begin
  writeln('sizeof by value:',sizeof(arr));
end;

procedure f_ref(var arr: arr_t);
begin
  writeln('sizeof by reference:',sizeof(arr));
end;

begin
  f_val(arr);
  f_ref(arr);
  writeln('sizeof as global:',sizeof(arr));
end.

... és ezt adja vissza:

charlie@chainmbp-m2 arr_t % ./arr
sizeof by value:1337
sizeof by reference:1337
sizeof as global:1337

És akkor még olyan finomságokat nem is részleteztünk, hogy a length() is hasonlóan működik, szóval az elemszámot is le lehet kérdezni, nem kell sizeof-ból és az elem méretéből számolgatni, sőt, mivel Pascalban a tömbindexek range típusok (lehet egy tömböd boolean index-szel, vagy akár -13-tól +27-ig), ezért a low(tömb) mindig a legalacsonyabb, a high(tömb) mindig a legmagasabb elemszámot adja vissza, ami igen hasznos index-ellenőrzéshez, vagy akár egy tömbön végig-iteráláshoz, és ha megváltoztatod az eredeti típust, minden automatikusan marad a helyén. stb. Ja és igen, statikus méretű tömböknél ezek fordítás közben konstansokra cserélődnek, nem valamiféle management helper lesz meghívva. Amikor azt mondom, a Pascal típusrendszerét és a körülötte lévő infrastrukturát preferálom, ilyesmikre gondolok. Vagy pl. itt egy példa a set-ek, tömbök és enum-ok együttműködéséről, amit még régebben írtam. Hogyan tudja egy konzisztens típusrendszer és a kapcsolódó adatszerkezetek masszívan leegyszerűsíteni és biztonságosabbá tenni a kódot, ugye.

Na mindegy. Nem akartam belemenni, de ha már cizellálunk. :)

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

A C olyan, hogy látnod kell magad előtt, mivé fordul, mi lenne ott a fordító szándéka, hogyan csinálnád assembly-ben. Nekem a pascalos viselkedés a furcsa a példádban. Félnék olyan nyelvtől, amelyben ez így van, mert nem értem, hogyan csinálja meg.

C-ben világos, hogy amikor átadtad a tömbre mutató pointert a függvénynek, fogalma sem lesz róla futásidőben, hogy a pointer mire mutat. Olyannyira nem, hogy C-ben nem kell a tömböd elejére mutatni a pointernek, meghívhatod így is:

func(arr + 5);

És akkor mit mondjon erre egy békés sizeof? Ott az csak egy pointer, ami 64 bit, az meg 8 byte, így természetesen 8-at ad vissza. Fogalma sincs func()-nak arról, hogy amivel hívod, az egy milyen hosszúságú micsoda, egyáltalán azonos típusú tömb-e, vagy cast-oltál, vagy belemutatsz a tömb belsejébe, vagy olyan címre mutatsz, amely nem is tartozik a processhez, és segfault lesz belőle. Mert az is lehet. Egyedül a NULL-ra tudsz vizsgálni. :) Szóval ezt a hívó helyen kell tudni, vagy a hívott függvénynek elmesélni, mennyi adaton garázdálkodhat a függvény.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A pinter az pointer, a tömb meg tömb. Ha a tömb valójában pointer, akkor miért van saját neve?

A C-hez készült biztonságosságra vonatkozó előírás (pl. MISRA) mindig azzal kezdődik, hogy a tömbnek mindig át kell adni a méretét is! Ha átadjuk úgyis, akkor miért ne fogja egybe a két dolgot a fordító? Hogy te nem tudod, hogy mire fordul? Hát mert nem tanultad meg. De ha megtanulnád, akkor tudnád.

A tömb az a memóriában lefoglalt terület, de nem adod át a stack-en, nem memcopy-zol, mert vinné a futásidőt és zabálná a stack-et. Bár jobban belegondolva szerintem struktúrát át lehet adni, abban meg tömböt is, csak eléggé nagy butaság, irgalmatlan lassú lesz. Pointert szoktunk átadni, de az nem visz magával más tulajdonságot, például elemszámot. De az elemszám ingoványos, ha a pointer történetesen nem a tömb nulladik elemére mutat. Amúgy típust sem visz magával, csak van egy olyan jó szokásunk, hogy olyan típusú pointert deklarálunk, amilyen típusú tömbön dolgozni akarunk, de ez nincs szükségképpen így. Viszont senki sem akadályoz meg abban, hogy deklarálj egy struktúrát, amelynek egyik eleme egy pointer, a másik egy elemszám, majd ezt a struktúrát add át a függvényednek. A C-ben épp az a jó, hogy ezt is meg lehet csinálni, de nem muszáj. Alkotói szabadságodban áll.

Mondvacsinált ez a sizeof probléma. Olyan ez, mintha létrehozna valaki egy void fnc() függvényt, majd utána azon nyafogna, hogy nincs visszatérési érték. Na jó, de ha úgy hozta volna létre, hogy legyen, akkor van visszatérési érték.

Ugye, az sem mindegy, hogy

stuct {
  char *name;
}

vagy

struct {
  char name[32];
}

módon hozunk létre egy típust. Előbbiben egy pointer mutat a bárhol lévő bármilyen hosszú stringre, míg utóbbi esetben a változó ténylegesen tartalmazza majd a legfeljebb 31 karakter hosszú stringet.

Meg ugye a printf("%s speed\n", flags.speed ? "Low" : "High"); esetében sem adtuk át paraméterül egyik stringet sem. Mindhárom string valahol, jó messze lesz a memóriában, s a rájuk mutató pointer kerül átadásra.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

>nem adod át a stack-en, nem memcopy-zol, mert vinné a futásidőt és zabálná a stack-et.

De hol marad az alkotói szabadság? :-) Ha én át akarom adni a stacken, akkor miért ne tehetném meg? Épp ez egy kognitíven nehéz része a C-nek, hogy sima változó érték szerint megy át, a tömb viszont csakis pointerként, és "automatikusan" a tömb neve egy pointer is. Nekem már nem az, mert elég rég tanultad hozzá, hogy mostanra természetes legyen.

>senki sem akadályoz meg abban, hogy deklarálj egy struktúrát, amelynek egyik eleme egy pointer, a másik egy elemszám, majd ezt a struktúrát add át a függvényednek.

Ha belegondolsz az lenne az ésszerű, hogy ez lenne az alapműködés, mert az esetek 99%-ában át kell adni a méretet is. És ha véletlenül nem kell, akkor arra volna való a pointer, ami nem tömb, hanem pointer.

Valahol igazad van, de szerintem a nyelv megalkotója abból indult ki, hogy a tömb nagyon nagy lehet, akkora, ami nagyobb az egész stack-nél, s nem jó ötlet megabyte-okat duplikálni, makroszkopikus idők alatt függvényt indítani. Úgyis mindenki referenciával használná a tömböt, szóval a tényleges átadás a ritkább. Amúgy van egy másik eset is, amikor a jelölés nem a tartalmat, hanem a címet jelenti. Ha egy táblázatban felsorolsz függvényneveket, úgy azoknak a függvényeknek a belépési címeit jelenti ez, nem kell elé írni az & jelet. Tipikusan parancsértelmezőben, vektoros vezérlés átadásnál használjuk a függvénypointereket, amikor van egy táblázat, annak egy-egy eleme egy-egy parancshoz tartozik, a táblázatban az adott parancshoz tartozó végrehajtandó függvény címe.

Amit viszont nem szeretek, az a const. Ha van egy string táblázatom, mi a konstans? A stringek, a rájuk mutató pointerek, mindkettő? Tudom a megoldást, nem kell leírni, de ennek a jelölése már valóban eléggé gyilkos.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ez az eszmefuttatás egész addig érvényes, amíg rá nem jössz, hogy a struct-ok viszont érték szerint adódnak át, ergó lemásolódnak és működik rájuk a sizeof... Sőt még cím szerinti átadás esetén is megy. Semmi oka nincs, hogy tömbökre, legalábbis konstans méretűekre miért ne tudna ugyanígy működni - azt leszámítva, hogy a nyelv nem így működik - azaz szarul. :) Nem különböztet meg konstans méretű és dinamikus méretű tömböket, és hiába ismert egy statikus méretű tömböd mérete, valamiért ez az infó elveszik paraméterátadáskor. Az arr + 5 példa számomra teljesen rossz, és pont annak a példája, hogy a C olyasmit is megenged amit nem kéne - az "arr + 5" számomra egy 1337 elemű tömböt kéne hogy jelentsen attól a címtől kezdve, hiszen az van a típusban - de nem azt fog. Nyilván így nem is tud működni a sizeof(), ezt is értem. De pont ez a problémám a C-vel, hogy _szerintem_ ez így értelmetlen, de ezt elmagyarázni valakinek aki ebben él olyan, mint egy német vagy angol nyelvi beszélőnek hogy a nemre tagolt személyes névmásoknak kb. semmi értelme és lehet enélkül létezni, sőt... Jót tesz mentálisan. :)

Struct-os példa:

#include "stdio.h"

typedef struct {
    char arr[1337];
} struct_t;
struct_t struc;

void func_v(struct_t struc)
{
  printf("v struc: %ld\n",sizeof(struc));
  printf("v struc.arr: %ld\n",sizeof(struc.arr));
}

void func_r(struct_t *struc)
{
  printf("r struc: %ld\n",sizeof(*struc));
  printf("r struc.arr: %ld\n",sizeof(struc->arr));
}


int main() {
  func_v(struc);
  func_r(&struc);
  return 0;
}

Kimenet:

charlie@chainmbp-m2 arr_t % ./a.out
v struc: 1337
v struc.arr: 1337
r struc: 1337
r struc.arr: 1337

Mint látható, akkor is konzisztensen működik, ha cím szerinti átadás történik... a fenti nem ijesztő akkor? Ezt vajon hogy csinálhatja a fordító! Fekete mágia...! :) Rettegjünk együtt... A válasz amúgy kb. az mint a C, a Pascal, vagy bármilyen más nyelv esetében - tudnod kell mit csinál rá a fordító, és a nyelv. Semmi ijesztő nincs benne. De attól még lehet véleményed arról, hogy egy szabály rossz vagy nem. És nem kell aggódni, a Pascalban, főleg az Object Pascalban van jópár olyan dolog, amit ugyanígy nem konzisztens... De legalább az alapok egyben vannak.

Najó hagyjuk, tényleg...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Nem veszekszünk, meg ez nem politika, szóval lehet róla beszélni. :)

Struktúra másabb, a típusból következik a méret, a tagok offset-je. Tömbnél meg nem, mert nem a tömbnek van típusa, hanem a tömb elemének, és az egyik - még csak nem is feltétlen a nulladik - elemének címét adod át.

Viszont egy lehetséges megoldás, hogy struktúrában adod át a tömböt, bár nem tudom, kinek hiányzik egy rakás memória másolása.

Arról valóban lehet beszélni, hogy logikus-e az, hogy míg struktúra esetén az egésznek van egy típusa, addig tömb esetén csak az elemnek van ilyenje, de szerintem ez épp nagyobb mozgásteret és kreativitást biztosít a programozónak.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

kinek hiányzik egy rakás memória másolása

A C pointer-jellegű tömbjeitnek stílusát is lehet használni modern Pascalban. Ami a jó benne, hogy egyértelműen meg kell jelölni az ilyesmit a szintaxisban mint pointer-művelet, nem csak "valami lesz, szokjad". Ugyanúgy mint a cím szerinti átadást is (var/const kulcsszóval, esetleg külön pointertípussal). Szóval nem limitál ez semennyiben sem, se nem lassabb, csak máshogy kell hozzáállni - és még így is jobban fogja a fordító a kezed, hogy ne ess hasra. Most mondjam azt, hogy fogtam már bugot C kódban azzal hogy Pascalba portoltam, de meghagytam a C stílust? A Pascal fordító be is sírt egy pár dologra, nézem, hát tényleg. Nézem a C kódot, ott is olyan. "Upsz." Cserébe meg C-ben van az, hogy egy rakás kézimunka lesz, ha véletlenül mégis át kell másolni a tömböt. Valszeg valami kézi memcpy() vagy környéke lesz, megint csak méretszámolgatással. Rengeteg buglehetőség... Pedig a fordító is megtehetné neked...

de szerintem ez épp nagyobb mozgásteret és kreativitást biztosít a programozónak

Pont ez az ősi C érv, amit kb. 30 éve hallgatok, hogy "de minden más limitálja a kreativitásom" vezetett a hálózatok és aztán internet világában egy rakás biztonsági problémához, és gyakorlatilag közvetlenül a newschool C-t leváltani akaró nyelvek többségéhez, amelyek mindegyike sokkal szigorúbb ebben. Vagy akár a "modern" C++ beteges rettegését a pointerektől is említhetnénk, ami szintén itt gyökerezik. Szóval erről szerintem már bebizonyosodott, hogy ez az érv nettó arrogancia a C programozók részéről, és semmi több.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

erről szerintem már bebizonyosodott, hogy ez az érv nettó arrogancia a C programozók részéről

Ez filozófiai különbség. Van, aki a szabadságot szereti, van, aki járókeret és mentőmellény nélkül a mosdóba sem hajlandó elindulni, mert a 8 m-es úton egy kezében kávéval közeledő kollégája elütheti. Nem vagyunk egyformák, én szabadságpárti vagyok. :)

Mondjuk úgy, ezen új nyelvek létrejötte azok igénye volt, akik nem tudnak programozni, nem bíznak saját magukban, a kollégáikban, vagy ki akarják szervezni a programozási feladatokat kebab árusoknak.

Én már attól ideges vagyok, amikor az x = (x ^ b) & ~m ^ b; kifejezésemre benyögi a fordító, hogy tegyem ki a zárójelet az & operátor két operandusa által határolt helyre is. Minek? Az & precedenciája magasabb, mint a ^ precedenciája. Vagy akkor az 5 * 6 + 3-at is (5 * 6) + 3 alakban kell legközelebb leírnom? Ne már! Egész egyszerűen kezdik hülyékre skálázni a szakmát, és ehhez új, fűre lépni tilos táblákkal, korlátokkal teletűzdelt nyelveket alkotnak.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Na ezt megmutattam egy par Scala programozonak, akik hetente termelnek cegeknek par 100 millio dollart es ellege bonyolult problemakat oldanak meg, hogy tudjak hogy nem tudnak programozni csak kebabos hulyegyerekek es a problemak sem igazi problemak. :D

Remélem, a kontextust is sikerült értelmezni. Arról volt szó, hogy többen szapulják a C nyelvet, ami véleményem szerint jól van kitalálva, nagy szabadságot enged. Amúgy hogy jön ide, mennyiben releváns, hogy ki mennyi pénzt hoz össze? Programozási nyelvekről beszélünk, ami akkor is az, ami, ha valaki hobbi programozóként használja, és semennyi pénzt nem termel vele, vagy veszteséges, mert a pizzáját is más bevételből kell fedeznie.

A C eleve nem objektumorientált, de szerintem most nem erről volt szó, hanem arról, amikor a nyelv nem enged a hardware közelében, illetve kiveszi a programozó kezéből a hardware elérését, valamint korlátok közé szorítja a programozót, mert a nyelv maga majd jobban tudja, mit akar a programozó. Erre mondom én, hogy nem, nem tudja jobban.

Egyébként a kollégáid inspirálására, az ő igényeikre jött létre a Scala?

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Egy nyelv nagy szabadságot engedhet meg abban, hogyan csinálsz meg dolgokat és abban is, hogy mit tudsz megcsinálni vele. A kettőt nem jó összekeverni. A C éppen azért született, mert egy csomó korlátot berakott a korábbiakhoz képest, de közben megmaradt a szabadsága annak, hogy mit tudsz vele megcsinálni. Pl. az, hogy vannak statikus típusok, az egy hatalmas korlát.
A goto az pedig pont arra példa, hogy bár van a C nyelvben, mégsem ajánlott használni, mert mindent meg tudsz nélküle csinálni a korlátos eszközökkel (for, while, break, continue, függvények).

Here's a quote from Bjarne Stroustrup, creator of C++, "The fact that 'goto' can do anything is exactly why we don't use it."

A mai modern nyelvek ezt a vonalat viszik tovább, még több korlátot visznek a nyelvbe, de semennyire sem csorbul az a rész, hogy mit tudsz vele megcsinálni, sőt! Ezt bizonyították is valamelyest ebben a versenyben a megoldások.

Egy kis példában be is mutattam, hogy, ha korlátok között írsz meg valamit, akkor a fordítás során sokkal jobban tudja optimalizálni a fordító az adott részt akár méretre, akár sebességre, akár párhuzamosságra, ... Mivel ilyenkor a "hogyan"-t kedvére megváltoztathatja úgy, hogy a "mit" nem változik.

"Mondjuk úgy, ezen új nyelvek létrejötte azok igénye volt, akik nem tudnak programozni, nem bíznak saját magukban, a kollégáikban, vagy ki akarják szervezni a programozási feladatokat kebab árusoknak."

Ez nagyon tetszett nekik. Jot nevettek rajta. Volt aki meg assembly demoscene-eket is irt vagy mifaszomat (szoval feltetelezem ez az amikor neked all a pelo kemenyen, es akkor megse annyira hulye a srac (mondjuk 54 szovel nem annyira srac), na o annyit mondott, hogy "cukifiju" vagy. :D

Abban az irományban (eredeti angol) az a kedvencem, hogy ekézi a Pascal programozókat - lássuk be, az átlagost valószínűleg jogosan, pl. ilyen megállapításokat téve hogy:

A legtökösebb igazi programozók közül néhány a Jet Propulsion laborban dolgozik Kaliforniában. (...) A jelenlegi tervek szerint a Galileo űrszonda gravitációval segített pályán fog menni a Mars mellett a Jupiter felé. Ez a pálya 80+-3 km-re halad el a Mars felszíne fölött. Ilyen pontosságú navigációt senki sem bízna egy Pascal programra (vagy egy Pascal programozóra).

Ez egész addig tök jól hangzott és lehetett röhögni, amíg az igazi programozóknak össze nem sikerült keverni a metrikus és a birodalmi mértékegységeket, és 1999-ben a Mars Climate Orbiter el nem égett a Mars légkörében a p*csába. De hát ez egy régi szöveg, na... Szóval ezért mondom, hogy az - egyesek által - itt hangoztatott C a nagy szabadság az kb. az "addig jár a korsó a kútra" tipikus esete. No mindegy.

(Ugyanott a szöveg említi a Boeinget is, mint az igazi programozók fellelési helyét... Azt már fel sem hozom, annyira magas labda...)

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Hú, a Mars szondás le se esett nekem! Pedig mennyire kézenfekvő! Tényleg az van, hogy a C fanok írása a saját ellenpropagandájuk.

Akkoriban azon gondolkodtam, hogy hogyan kell jól kezelni a fizikai egységeket programban, és arra jutottam, hogy minden mértékegységnek külön típus kell, és a típusok közötti átváltás explicit cast, ami elvégzi a kellő számítást. És persze ezt a compilernek ki kell kényszeríteni (el is kezdtem egy ilyen nyelvet írni annó).

A típus tehát nem csak az ábrázolás mikéntjét kell hogy tartalmazza (hány bit, integer vagy floating, stb), hanem az érték szemantikáját, azaz a mértékegységét is. Programozónak elsőre fura, de egy fizikusnak ez lenne a természetes. Itt aztán a C programozók egyből felgerjednének, hogy mi az, hogy nem írhatják az inch típusú változó értékét a méter típusúba? Miért nem adhatjuk össze őket? Hiszen mindkettő 32 bites float! Hát igen, de egyszerűen soha nem állhat olyan helyzet elő, hogy értelme volna métert inch-csel összeadni számértéken. Előbb közös mértékegységre kell hozni őket.

Ha én nem is fejeztem be, de vannak akik el is készítettek egy ilyen libraryt: Squants.

The Scala API for Quantities, Units of Measure and Dimensional Analysis

Squants is a framework of data types and a domain specific language (DSL) for representing Quantities, their Units of Measure, and their Dimensional relationships. The API supports typesafe dimensional analysis, improved domain models and more. All types are immutable and thread-safe.

és arra jutottam, hogy minden mértékegységnek külön típus kell, és a típusok közötti átváltás explicit cast, ami elvégzi a kellő számítást. És persze ezt a compilernek ki kell kényszeríteni (el is kezdtem egy ilyen nyelvet írni annó).

Ezt a nyelvet már feltalálták: C++ :D

Azért a kettő nem ugyanaz, mert az enum egy C nyelvi elem, a #define meg a nyelvfüggetlen precompileré.

(Például ha Assembly fájlokból is be kell húzni ugyanazt a fejlécet, akkor nagyon nem mindegy, mert míg az enum-ra hibát dobna, addig a #define simán működik, mert azt a precompiler még azelött feloldja, hogy az Assemblernek átpasszolná értelmezésre. Ebbe a hibába konkrétan belefutottam egyszer, bár tény, viszonylag ritkán van szükség arra, hogy egy nevesített konstanst C-ből és Assembly-ből is egyaránt el kelljen tudni érni, elég speciális eset.)

ez a verseny pontosan azt mutatta meg, amit meg akart mutatni: eleve értelmetlen ez, és hülyeségeket hord össze, aki a C lecsérléséről beszél.

Most akkor nem a Zig nyert a C-vel, meg minden mással szemben? Mondom mindezt úgy, hogy elfogult vagyok C irányában, számomra ez az egyetlen értelmes nyelv, ami memóriacímet, memóriába ágyazott regisztert lát közvetlenül, elég tömör, mégis eléggé szabadon lehet benne bármit csinálni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

De. A beérkezett megoldások és a kiírt szabályok alapján ha a C leváltásra kerülne valaha, akkor erre jelenleg a legnagyobb esélye a Zig-nek lenne. Hipotetikusan, mert a C egész biztos jó darabig nem megy még sehova.

Ha nagyon paraszt akarnék lenni, akkor úgy foglalnám össze az eredményt: a Holdról is látszik, hogy még véletlenül sem a Rust az esélyes. De nem vagyok paraszt :-)

off

Nekem néha van olyan érzésem, hogy ha van C, akkor minek bármi más.

Azt állítani, hogy "csak C" pont ugyan olyan hülyeség, mint azt állítani, hogy "csak Rust" vagy "csak Vala" stb.

Csak azért, mert a C tényleg mindenre használható, még nem jelenti azt, hogy egy adott célfeladatra ne létezhetne jobb és kényelmesebb megoldás. Például csak azért, mert a C alkamas még szkriptelésre is (lásd TCC, QuakeC stb.), én sose állítanék egy akkora faszságot, mint hogy a "C leváltja a shell szkriptet", ahogy ezt az elvakult Rust fanboyok teszik.

Az egész felvetésed szerintem téves. Egy szimpla "count" nem méri egyetlen programozási nyelv, környezet, megoldás jóságát, nem mutat meg semmit.

Mivel semmi speciális nincs benne, így egyetlen programozási nyelv sajátos képessége (amitől különbözik egyik a másikról..) nem érvényesül.

Ez így egy nagy faszság, bocs...

 

Ugyanakkor, hogy itt lényegében már csak szájtátás meg járatás van (a fórumon) azzal mélységesen egyet értek...10+ évvel ezelőtt ez egy szakmai fórum volt, ma már csak pár haver ossza annak a pár pofonért önként jelentkezőnek, hogy "hülye vagy fiam" - de amikor kicsit bonyibb a dolog, befuccsol és személyeskedésbe fullad...hisz a kérdező nem tartozik a haveri körbe...

10+ évvel ezelőtt ez egy szakmai fórum volt, ma már csak pár haver ossza annak a pár pofonért önként jelentkezőnek, hogy "hülye vagy fiam"

Hat, ez ilyen.

Valahol megertem a masik oldalt is, amikor kerdeznek, te veszed a faradsagot es utanajarsz, vegiggondolod es valaszolsz, majd:

  • kitorli a kerdezo a threadet
  • szetoffoljak baromsagokkal a threadet
  • csak rakerul a [megoldva] cimke, aztan nyomozd ki, mi lett a megoldas, vagy hogy egyaltalan abban a threadben hangzott-e el
  • valaszolsz, es leoltanak, hogy nem jo a valaszod
  • XY problema
  • eleve hulyeseg/trollkodas volt a kerdes

En "csak" 15 eve vagyok regisztralva, elotte read-only voltam par evig. Mindig is volt falkazas, mindig is voltak trollok, legfeljebb neha cserelodtek. A politikai spam persze nem segitett, de nem igaz, hogy 10+ eve mas volt a helyzet.

gelei téged pl Én speciel tisztellek, bár vannak neked is olyan hozzászólásaid hogy csak na...

Annak örülök hogy a falkázást nem vitatod és látod Te is hogy kicsit sem szerencsés.

Többnyire egyet is értek az "elhangzottakkal" amit felsoroltál mint "másik oldal" - de az kétségtelen hogy ha befogadóbb a falka, csak akkor képes bővülni, nőni.

Én régebben szívesen bővítettem volna, de úgy láttam hogy nincs rá igény...