Reaktionære og forstokkede !

Med den overskift kan det næsten kun handle om politikere, chefer, kunder og marketingfolk, ik' sandt ?

Det gør det ikke.

Det hander om systemprogrammører.

Donald Knuth begyndte på "The Art Of Computer Programming" i 1962 og de første tre bind udkom i slutningen af tresserne. Næste år har første bind 40 års jubilæum.

Få år efter, i 1972, kom sproget 'C' til verden, primært Dennis Richies fortjeneste.

Vi har altså haft 35 år til at få avancerede datastrukturer, som f.eks lister, stoppet ind i vores primære systemprogrammeringssprog, men er vi kommet nogen steder ?

Overhovedet ikke.

Jeg har i nogle år puslet med en opgradering til C som ville overtage disse basale datastrukturer så jeg kan slippe for monstrøsiteter som:

define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \

(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
TAILQ_NEXT((elm), field) = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
} while (0)

Det der pisser mig af er når jeg taler med nogen om dette projekt, så er en af to reaktioner 100% sikre: Enten slår de korsets tegn for sig, eller også begynder de at tale om C++ og/eller Java.

Dem der taler om C++ og Java kan vi se bort fra, de kender tydeligvis ikke noget til forholdene i en UNIX kerne.

Dem der slår korsets tegn for sig, mens de intonere en bøn om beskyttelse imod falske profeter og afvigelse fra C9X standardens hellige ord, undrer mig derimod såre.

Vi kan formodentlig hurtigt blive enige om at ISO-C ikke ligefrem er banebrydende. Når folk i det her årtusinde kan falde i svime over "sparse struct/array initialization" så er der noget galt. Helt, HELT, galt.

Hvis sproget C havde fulgt med tiden, så havde det som et minimum haft følgende faciliteter på nuværende tidspunkt:

  • linkede lister
  • integers af arbitrær størrelse
  • enums som sande typer
  • en simpel objektmodel (ie: structs+methods)
  • integer domain restrictions "int i {0...9};"
  • struct pointer validation via hidden magic number

Når man så nævner den slags, kan folk som regel godt se at der er et lille efterslæb i ISO-C, "men på den anden side, er du sikker på du ved hvordan det skal virke ?"

Det er her jeg altid ville ønske at jeg havde taget The Art Of Computer Programming med, så jeg kunne pege på udgivelsesåret med sarkastisk mine.

Hvorfor er systemprogrammører så reaktionære og forstokkede ?

Hvis vi bliver ved med at bruge et stenalder sprog som C, så er der vel ikke noget at sige til at vi aldrig kommer videre ?

phk

Kommentarer (23)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Mads Olesen

Hej Poul-Henning!
Du må undskylde den provokerende overskrift :-)
Men når du for under en måned siden ( http://www.version2.dk/artikel/1553 ) har afvist at udskifte Troff med LateX (Som er fra 1983), så må man da lave sig visse tanker om du egentlig er et hak bedre selv?
Det handler vel dybest set om at de gamle hunde har vænnet sig til tingenes tilstand. Og hvis nogen snakker om et nyt programmeringssprog, ser de straks for sig hvor meget de skal til at lære forfra.

Start du hellere med at programmere lidt Java/Python/C#, og studer evt. singularity ( http://research.microsoft.com/os/singularity/ ) lidt.

Poul-Henning Kamp Blogger

Helt ærligt Mads, det er for billigt...

For det første ikke Troff mere og jeg mener heller ikke LaTex er særligt tidsvarende mere.

Desuden er det meget underlødigt angreb, når netop jeg har arbejdet med at formulere problemet og identificere mulige løsninger i flere år.

Med hensyn til dit forslag om Java, Python og C# kan jeg henvise dig til at læse mit indlæg igen: ingen af disse sprog kan bruges til at implementere et POSIX operativsystem med på hardware som vi kender den idag.

Poul-Henning

Karsten Nyblad

Jeg kunne godt lide at vide, hvad der gør, at du ikke kan bruge C++. Mit gæt er, at du vil kunne styre, hvor dine data blive allokeret, men det kan du faktisk i C++. STL's implementering af lister, stakke, osv. er baseret på en allokcation class, og den kan udskiftes, når du instantierer en klasse. Syntaksen er noget i retning af: List<element_type, allocation_class>.

Så er der Ada, som burde være egnet til programmering på kerne niveau. Hvorfor kan du ikke bruge Ada?

Michael Rasmussen

Jeg kan oplyse, at der rent faktisk er nogen, der har prøvet at implementere dele af Linux kernen i C++, men det forsøg fik en hurtig død. Jeg kan ikke lige huske referencen, men forsøget blev beskrevet i et interview med Linus, hvor han forklarede hvorfor, at C var eneste reelle alternativ.

Poul-Henning Kamp Blogger

C er vores portable assembler sprog, der stilles ingen krav om runtime support eller hukommelsesmodel.

Derfor bruges C til programmering af alt fra operativsystemer til microcontrollere.

C++, Python, Java, C#, Ruby osv, forudsætter alle at de kører i et POSIX-lignende miljø med adgang til dynamisk hukommelsesallokering osv.

Det påstås fra pålidelig kilde at der findes en "cut down" version af Ada der kan bruges til systemprogrammering, men jeg har ikke selv checket den.

Poul-Henning

Peter Makholm Blogger

Jeg tror det er let nok at se hvilket ting Poul-Henning gerne vil have i sit nye sprog, mere problematisk er det nok at indse hvad det er han ikke vil have. Derfor begynder folk at tænke Java, C++ og diverse andre ting når de hører Poul-Hennings rant.

Et sprog det i praksis er baseret på en eller anden form for bytecode eller virtual machine er selvfølgelig no-go til lowlevel-programmering.

"Simple objekter" opfatter jeg netop som 'structs og metoder' - ikke klassenedarvning og da slet ikke multipel arv. Jeg tror at en masse "skjult" kode for at håndtere typesystemet på køretiden er uønsket.

Jeg synes det kunne være inteeressant hvis Poul-Henning istedet for bare at sige hvad han ville have, også skrev hvad han ikke ville have.

Michael, Jeg tror du skal skelne mellem det konkrete sprog Objective-C (objc), der stadigvæk bliver brugt i NeXTSTEP-afledte systemer og "C with Objects" der er et mere abstrakt begreb der blandt andet også er blevet brugt om tidlige versioner af C++.

Karsten Nyblad

Det er ikke rigtigt, at C++ er så tæt bundet op på dynamisk hukommelsesallokering, at det ikke er muligt at lave programmer, der ikke bruger den. Både new og delete er operatorer, der kan redefineres. Det er muligt, mange compilersystemer mere eller mindre per automatik linker et runtime bibliotek på programmerne, men det er ikke C++'s fejl.

Lad os kigge lidt på TAILQ_INSERT_BEFORE. Den benytter sig af feltnavne, der bliver overført per parameter, men feltnavnet tqe_prev er kodet hårdt ind i makroen. Hvordan skal vi få sådan noget med i et programmeringssprog? Tja, det er allerede i C++, men det sprog kan Poul-Henning ikke lide. Hvordan skal man allokere listeelementer? Poul-Henning kan ikke lide new og delete fra C++, men har ikke forklaret os, hvordan han så vil håndtere problemet.

Pou-Henning, jeg tror, at enten ender du med et sprog, der er specialdesignet til at kode kerner, eller også kan du lige så godt bruge C++ i en variant, der ikke automatisk linker runtime biblioteket på.

Poul-Henning Kamp Blogger

Først,TAILQ eksemplet kan ses i sin fuldskab her:
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h?rev=1.68;conte...

En slidt gammel joke siger at man kan skrive FORTRAN i alle programmeringssprog.

Min pointe er at sproget skal hjælpe programmøren til at løse sin opgave og i særdeleshed skal det programmøren ikke bruge tid på at lægge arm med sproget og compileren, for at få sin vilje.

Jeg tror ikke min C dialekt bliver specialdesignet til at skrive kerner, det bliver specialdesignet til systemprogrammering, hvoraf kerner en et meget vigtigt subset.

Men selvom det så skulle blive et sprog der kun kan bruges til at skrive operativsystemskerner i, er det så ikke en så central og vigtig opgave, at man bør bruge sprogdefinitionen og compileren til at forbedre resultatet ?

Det kan da for pokker ikke være meningen at vi i dette årtusinde skal have kerner der styrter i grus, fordi en programmør manuelt skal holde styr på next & prev pointere i en liste ??

Jeg har nogle ideer til mit sprog, men ikke en færdig syntax. Det helt centrale i ideen er at gøre sproget til et aktivt værktøj og ikke et passivt instrument.

Poul-Henning

Lasse Bach

Hej Poul Henning.

På Linuxforum snakkede i (under OpenBSD-foredraget) om hvordan det kommer til at se ud med den fremtidige brug af gnu's c-kompiler. Der var vist noget omkring den nye version af GPL'en, uden at jeg kan huske hvad.

Min kammerat og jeg snakkede dog om, at det kunne være spændende at se et fælles compiler-projekt mellem BSD'erne. Så kunne i få jeres egen BSD-licenserede compiler, og i vil vel også have mulighed for at udbygge C??

Jeg er godt klar over, at det er et stort projekt, men er det en helt dårlig ide?

Venlig hilsen
Lasse Bach

Jacob Sparre Andersen

Personligt mener jeg at Ada minus køretidsbibliotek (og eventuelt plus brug af SPARK Examiner) er lidt smartere end C til at skrive kerner i. Men det har ikke alle de fordele Poul-Henning spørger efter.

Ganske som de fleste andre sprog er Ada ikke kommet længere end til »array« når det gælder datastrukturer der er med i sproget på 1.-klasse. Der er ganske vist hægtede lister, hash-tabeller og andet godt med i standardbibliotekerne, men det er ikke det samme som at have datastrukturerne indbygget i selve sproget.

Er problemet at alle datastrukturer ud over »arrays« har for mange forskellige implementationsvarianter? Er sprogdesignerne bare for dovne? Eller er problemet at vi insisterer på at vores programmeringssprog skal være små, og at vi derfor lægger så meget som muligt ud i biblioteker, uanset om det er vigtigt nok til at det bør være en del af selve sproget?

Jacob

PS: Jeg kunne godt tænke mig at være med til at skrive en oversætter til et sprog der tager nogle flere af de vigtige datastrukturer ind i selve sproget.

Karsten Nyblad

"Er problemet at alle datastrukturer ud over »arrays« har for mange forskellige implementationsvarianter?"

Ja, netop. Skal lister være enkelt eller dobbelthægtede. Hvis de er enkelthægtede, skal det så være direkte pointer til at indsætte bagest i listen? Hvad skal der ske, hvis nogen ændrer listen, mens nogen andre gennemløber den? Hvor skal nye listeelementer allokeres henne? Hvad skal der ske, hvis man ikke kan allokere flere?

Nogen lister kan implementeres mere effektivt ved andre teknikker end hægtede lister. F.eks. kan man bruge arrays til proriterede køer og til stakke.

Poul-Hennings eksempel viser, at han gerne vil gemme listens links direkte i elementerne, men hvordan skal programmøren specifisere, hvilke links der skal bruges? I øvrigt forstærker sådan en implementering problemerne med processer, der ændrer en liste, mens en anden gennemløber den.

Jeg har meget svært ved at se, at fordelene ved at få lister ind i sproget opvejer ulemperne.

Poul-Henning Kamp Blogger

jeg er netop ikke ude på at få alt den der ekstra bagage med.

Jeg vil bare have noget i stil med:

tailq_head foobars;

struct foobar {
tailq_member list;
list_head my_children;
}

og så i koden kunne skrive:

struct foobar *fp;

tailq_insert_tail(&amp;foobars, fp, list)

Uden at skulle tænke på at foobars skal initializeres rigtigt, eller hvad next&prev pointere skal hedde osv.

Låsning og alle andre operationer skal netop som i C være explicitte.

Poul-Henning

Morten Olsen

Jeg er ikke sikker på jeg kan se hvad problemet er med C++, hvis man (i g++) oversætter med -fno-rtti og -fno-exceptions, og så bruger placement new og delete, så har man mange af de features som du efterspørger i "--C++". Og dem der mangler kan man sikkert lave med fuldstændig uforståelige og bizarre templates :)

/Morten

Karsten Nyblad

Hvis du bare ønsker at kunne bruge normale funktioner i stedet for grimme makrokald, så prøv at kigge på C++ faciliteten pointer to member. I C++ kan du definere en tailq_insert_tail function, der som tredie parameter tager navnet på et felt i en struct. I praksis vil C++ overføre et offset fra starten af structen til feltet. (Jeg må indrømme, at jeg aldrig selv har brugt pointer to member, da faciliteten er grisset i mine øjne.)

Hvis du ønsker, at lister skal være en ægte datatype i C, ja så ender du med at skulle lave alle de valg for brugerne, som jeg skitserede. Ellers får du en lige så kompleks grænseflade som C++.

Jeg tror, du er i gang med at genopfinde hjulet. Jeg tror ikke på, at du gør livet lettere for nogen, ved at opfinde en konkurrent til C, C++ og Ada.

Thomas Knudsen

Poul-Henning, kender du Walter Brights arbejde med "the D programming language" - se URL http://digitalmars.com/d/index.html hvorfra dette citat stammer:


D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. Special attention is given to the needs of quality assurance, documentation, management, portability and reliability.

D is statically typed, and compiles direct to native code. It's multiparadigm: supporting imperative, object oriented, and template metaprogramming styles. It's a member of the C syntax family...

Muligvis et partielt svar på nogle af dine bønner?

Thomas

Kim Højgaard-hansen

Ville bare lige supplere med at der jo findes et relativt udbredt OS skrevet i C++, nemlig symbian.

Udfra min ret begrænsede viden om at kode til det, virker det dog ikke ligefrem som om der er vundet nogen sejer ifht. at lave fejl. Det ser nærmere ud som om du skal være endnu mere "grundig" som programmør :S

Stephan Korsholm

De sproglige konstruktioner som du eftersøger findes i f.eks. Java og C#. Men det siger du er alt for langsomt? Det er blot ikke helt
rigtig:

  • Fortolket Java er ca. 5 - 10 gange langsommere end kompileret C

  • Kompileret Java er lige så hurtig som kompileret C

  • JIT kompileret Java er mindst lige så hurtig som kompileret C, og i mange tilfælde hurtigere.

Så er der mange andre parametre der kan sammenlignes som f.eks kodestørrelse, real-tids egenskaber osv. I det hele taget er det en kompliceret diskussion, men at sige at Java/C# er alt for langsom til embedded software udvikling er ikke rigtig.

Hos CISS i Aalborg har vi et samarbejde med KIRK telecom hvor vi har lavet et heterogent miljø hvor vi kan afvikle Java sammen med vores C legacy kode. Java software moduler kan sende beskeder til C software moduler og vice versa. Vi kører pt. fortolket Java, og da det er for langsomt til at håndtere centrale tidskritiske elemeneter bruger vi det til at lave GUI elementer med, hvor det egner sig fremragende. Vi har en VM embedded i KIRK's trådløse håndsæt og basestationer, og kan
foretage samtaler og opkald (hvilket er håndteret i C) samtidig med at Java VM'en kører stille og roligt i sit eget tempo. Senere laver vi kompileret Java og kan forhåbentlig rykke endnu mere fremtidig udvikling over på Java platformen.

Se i øvrigt også JamaicaVM'en her (http://www.aicas.com/jamaica.html).

Det er ikke enten/eller. Man skal kunne begge dele. Under alle omstændigheder er der brug for en revolution inden for indlejret software udvikling i ingeniør industrien i Danmark. Så denne diskussion er meget relevant.

Her er et eksempel på et stykke C kode (plukket fra et rigtig stykke software der faktisk kører derude):

"if (((ConnectionTimeOut&1)||((SdPtrFP->RxPtr->RxStatus.CRCresult&ALLOKMASK)==ALLOKMASK)) &&
(ActiveTransmitters<NUMBEROFTRANSMITTERS) &&
((SdPtrFP->RxPtr->Head&0xe0)==FMTHEAD) &&
((SdPtrFP->RxPtr->Tail[0]&0xfc)==0x00) &&
(SdPtrFP->RxPtr->Tail[1]==Fmid[0]) &&
(((SdPtrFP->RxPtr->Tail[2]^Fmid[1])&0xf0)==0))
goto ConnectEntry;"

Skræmmende !!!

Hilsen,

Stephan Korsholm, PhD studerende ved CISS, Aalborg Universitet,

P.S. Alt hvad jeg skriver her er for egen regning, og ikke godkendt eller gennemset af min arbejdsgiver.

Poul-Henning Kamp Blogger

Du glemte at vise os hvordan det tilsvarende stykke kode ser ud i ${dit_favorit_sprog}.

Jeg noterer mig at du er PhD studerende og derfor vil jeg give dig et hint: Ude i den virkelige verden er kode kun meget sjældent "rent".

Der er virkelighedsindtrængen fra alle sider: støj, transmissionsfejl, andre idioters misforståelser af standarder og specifikationer, hensyn til særlige kunder, produkter, fejltagelser, regnskabsregler, trykfejl og alt muligt andet.

Hvis du synes den stump kode der er skræmmende, så skal du finde dig et akademisk job når du har fået din PhD, du skal endelig ikke begive dig ud i verden udenfor.

Poul-Henning

Dennis Krøger

Hvis du skal have fat i hardwaren direkte, slipper du jo alligevel ikke uden om native/unsafe kode for at få fat i bestemte HW hukommelsesområder, så der ville den del sikkert være lige så "skræmmende" (hvorfor er den skræmmende? Der er ikke de store, onde ting i som jeg kan se, bare checks af at forskellige flag er sat (i hardware registrene, går jeg ud fra)).

Man kunne måske lave forskellige mappings til højniveau strukturer, men den slags abstraktioner gør det både meget langsommere, og sværere at holde styr på hvad der virkelig sker (Hvilket, for mig, ville være en del mere skræmmende).

Stephan Korsholm

Hej Poul-Henning

Så det du siger er at den "virkelige verden" er så kompliceret at man ikke kan lave pæn, læsbar kode? At den virkelige verden i sin natur er så kompliceret at den tilsvarende kode som modellerer den må forventes at blive så grim som den stump kode jeg viser ovenfor?

I følge min erfaring er sagen lige omvendt: Jo mere kompliceret et system du forsøger at programmere jo vigtigere er det at den kode man skriver er klar, simpel, tydelig og læsbar. Et sprog som Java har abstraktioner og biblioteker som gør det nemmere at lave "pæn" kode. Det kan man selvfølgelig også gøre i C/Assembler, men det er nemmere i Java/C#.

Hvad synes du iøvrigt om muligheden for at kunne afvikle dele af sin kode i Java og andre dele i C?

  • Stephan
Log ind eller Opret konto for at kommentere