Gå til innhold

Snart kan du få heftig spillgrafikk i nettleseren


Anbefalte innlegg

Du bør nok regne på det der.

 

Amazon selger båndbredde til 0.12 dollar per Gb for de første 10Tb iløpet av en måned, etter dette blir det billigere. Den billigste løsningen hos Linode (20$) inkluderer 2TB med båndbredde. Båndbredde er virkelig ikke så dyrt, hvis det hadde vært tilfellet hadde det nok ikke gått så bra for Origin, Steam eller Facebook (riktignok ikke spill, men mye båndbredde går inn og ut i form av bilder, og her tjener de nok mindre enn en krone per bruker).

 

Dette er en vanlig misforståelse.

Kode i seg selv kan være 100% feilfri. Hvis en programmerer har full oversikt over hvordan koden går fra f.eks. C til maskinkode, og derfra til mikrokode (noe er AMD- og Intel-spesifikt), og kontrollerer at ingen feil kan intreffe så er koden 100% feilfri. Dette er svært omfattende men gjennomførbart.

 

Jeg er klar over at det er teoretisk mulig at du kan ha feilfri kode, burde kanskje ikke vært så bastant, beklager. Men i praksis finner du utrolig skjeldent programmer som ikke inneholder bugs, som er hva utsagnet sikter til. Det er rett og slett utrolig vanskelig for en utvikler å forutse alle mulige måter koden kommer til å kjøre på, derfor blir det også utrolig vanskelig å programmere for alle mulige tilfeller, dermed bugs.

 

Jeg skjønner ikke hvorfor du mener at en utvikler kan forsikre seg om at koden er feilfri hvis han har oversikt over hvordan koden går fra f.eks. C til assembly og så til maskinkode. For det første er det ikke mulig. Ett enkelt "Hello, World!" program i C inneholder over en million tegn etter preprosessoren er ferdig, dermed skal det gjøres om til assembly, som er øker denne størelsen betraktelig.

 

Det er rett og slett ikke mulig at èn utvikler har kontroll på noe så massivt, eller at han kan være særlig produktiv med det, som er grunnen til at vi har høyere nivå språk til å begynne med.

 

Det er mye enklere å skrive feilfri kode i ett høyere nivå språk, enkelt og greit fordi det er mindre for utvikleren å tenke på enn om han skulle skrivd kode på ett lavere nivå. Leste her om dagen om en utvikler som sparte 75% antall linjer når han skrivde om programmet sitt fra C++ til Erlang (høyere nivå språk). Fra erfaring vet jeg at jo mindre programmet er, desto enklere er det å forutse/rette feil. Link: http://www.metabrew.com/article/rewriting-playdar-c-to-erlang-massive-savings

 

Med bare små forskjeller i javascript-implementasjoner så vil det bli forskjeller i koden som kjører i CPUen.

For å reduserer problemene med javascript bør det nok lages en enorm pakke med "unit testing", som sjekker omtrent alt tenkelig og tenkelig i spesifikasjonen. En litt lite spesifikk standard er ikke tilstrekkelig, ei heller en streng standard hvis det ikke verifiseres at denne følges til punkt og prikke.

 

Det sier seg selv at ulik kode vil gjøre ulike ting på CPUen.

Nå kan jeg ikke snakke for alle javascript implementasjoner, men V8 (javascript motoren til Chrome) har unit tests. Det er også generelt vanlig å ha unit tests eller test suites for språk implementasjoner, da det forenkler livet til utviklerne betraktelig.

 

Språkstandarder pleier også å være veldig konkrete. Javascript (eller skal vi se ECMAscript) standarden er også ganske godt skrevet.

http://www.ecma-international.org/publications/standards/Ecma-262.htm

 

Dette er en utbredt misforståelse. For det første er det ikke snakk om sikkerhet som i security, det refereres til "safety" som er tenkt å hindre utvikleren i å gjøre "dumme ting" som bryter med programmeringsparadigme. Det er altså lagt inn noen sperrer som skal hindre bestemte ting som i følge paradigmet ikke er en god idé, siden det muligens kan føre til ustabilitet. Dette forutsetter at programmereren har forstått paradigmet (hva det er og ikke er), men er i praksis ingen garanti for korrekt objektorientering eller håndtering av feil. Sammen med slike språk er det også en rekke patterns som typisk brukes, f.eks. MVC, hvor implementasjonen er svært kritisk for at det skal fungere. Språket bidrar ingenting her, og i tillegg har f.eks. MVC mange synkroniseringsproblemer som jeg ikke skal gå inn på her. Hovedargumentet for disse språkene er gjerne å unngå bryderiet med eksplisitte pekere og minneallokering, og erstatter dette med automatikk og "søppelinnsamling", som er kjent for både minnelekkasjer og for tidlig frigjøring av minne.

 

Ok, her virker det faktisk som om du ikke vet hva du snakker om. Det er veldig lite ett språk kan gjøre for å forhindre at en utvikler bryter med språkets paradigme. Det er ikke noe problem å programmere funksjonelt i ett objekt-orientert språk eller omvent. Paradigme er heller ingen regel, mer enn metodikk å jobbe på. Patterns er så kode som er vanlig å se for ett gitt språk, men er på ingen måte knyttet til språket. MVC (Model-View-Controller) er ett ganske standard mønster/pattern som er å se i Ruby(RoR), Python(Django), Objective-C(Cocoa), C# (ASP.NET) osv, både for GUI og Web-applikasjoner.

 

MVC i seg selv har ikke synkroniseringsproblemer, det er ett mønster, en måte å strukturere kode på. Det er godt mulig at koden enkelte skriver har synkroniseringsproblemer, det er faktisk ganske vanlig at kode som inneholder flere tråder er vanskelig å få til riktig i ganske mange språk.

 

Det er mange høynivå språk som benytter seg av en garbage collector, og ikke lar deg leke direkte med minnepekere. Grunnen til dette er at minnekorrupsjon, buffer- og stack-overflows er ganske vanlig i språk som gir deg tilgang på dette. Språk som Java, C#, Javascript er derfor sikrere, ifølge din egen definisjon, da de ikke tillater utvikleren å skyte seg i foten ved å lege med minnepekere, eller opprette minnelekasjer ved å glemme å frigjøre minne.

 

Hvis du har en garbage collector (søppelinnsamler) som lekker minne og frigjør minne tidlig, så har du en garbage collector som ikke fungerer. Å få til dette i Java og Javascript er en veldig vanskelig oppgave. Det er derimot enkelt å få til en space-leak, som flere utviklere feilaktig kaller memory-leaks, men som egentlig bare betyr at du tviholder på variabler du faktisk ikke bruker.

 

Det forbauser meg stadig hvordan både nyutdannede programmerere og mangeårige utviklere kan komme med utsagn som "det er sikkert fordi vi bruker Java", "vi bytter ut C med Java for å gjøre det sikkert" eller at "sikkerheten er i språket(Java, C#, Ada osv.)", og du er sikkert enig i at dette bunner i en fundamental misforståelse.

 

Men Java, C# osv. ER mer sikkert enn C. I C (og C++ for den saks skyld) så har du frie tøyler til å gjøre nøyaktig hva du vil. Det er ikke sikkert at dataen sier ifra hvis du gjør en feil (iterer forbi lengden av en array for eksempel), noe Java ville ha gjort. Java, og lignende språk, legger en del begrensninger på brukeren nettopp for å gjøre det vanskeligere for brukeren å ødelegge for seg selv.

 

En av de store fordelene med språk som kjører i en virtuell maskin som Java, er at hvis ett sikkerhetshull blir tettet i den virtuelle maskinen (JRE for eksempel) så vil dette hullet være tettet for alle Java-programmer. Dette får du ikke med programmer skrevet i C og C++.

 

For Firefox og Safari har de fleste alvorlige feil vært tilknyttet javascript, og javascript er ikke en ukjent trøblemaker for IE, Opera eller Chrome heller.

 

Tja, tror det er lenge siden selve språket javascript var ett problem for noen av disse nettleserne. Mange av sikkerhets-problemene med nettleserne (og da snakker vi sikkerhet som i security) er hovedsaklig relatert til sandboksen javascript kjører i. Javascript er vel egentlig mer sikkert enn eksempelvis Flash og Java, da det er lettere å forhindre javascript i å gjøre noe ulovelig enn å forhindre en plugin.

 

Javascript er forresten ett fantastisk språk å jobbe med. Men her vet jeg at jeg er blant minoriteten, de aller fleste er ikke så glad i javascript.

 

Jobber forresten som programmerer på fulltid. På dagtid jobber jeg med C/C++, noen ganger også Objective-C, Java og Lua. Hjemme jobber jeg mest med C# og Javascript.

  • Liker 1
Lenke til kommentar
Videoannonse
Annonse

Amazon selger båndbredde til 0.12 dollar per Gb for de første 10Tb iløpet av en måned, etter dette blir det billigere. Den billigste løsningen hos Linode (20$) inkluderer 2TB med båndbredde. Båndbredde er virkelig ikke så dyrt, hvis det hadde vært tilfellet hadde det nok ikke gått så bra for Origin, Steam eller Facebook (riktignok ikke spill, men mye båndbredde går inn og ut i form av bilder, og her tjener de nok mindre enn en krone per bruker).

Båndbreddekostnad: 0.12 * 1000 * 5.84 = 700 kr

Kostnad for VPS/server: ....

Så du må altså tjene minimum (700 + k) / 10.000 per kunde i reklameinntekter eller annet. Reklameinntekter alene vil kanskje være noe optimistisk med mindre spillet brukes iherdig. Jeg har aldri sagt at det er umulig, men båndbredde blir fort betydelig med mange TB i måneden, da må inntektene forutsigbart passere dette. (ikke at jeg ser noe poeng å kverulere over dette noe mer)

Jeg er klar over at det er teoretisk mulig at du kan ha feilfri kode, burde kanskje ikke vært så bastant, beklager. Men i praksis finner du utrolig skjeldent programmer som ikke inneholder bugs, som er hva utsagnet sikter til. Det er rett og slett utrolig vanskelig for en utvikler å forutse alle mulige måter koden kommer til å kjøre på, derfor blir det også utrolig vanskelig å programmere for alle mulige tilfeller, dermed bugs.

Jeg skjønner ikke hvorfor du mener at en utvikler kan forsikre seg om at koden er feilfri hvis han har oversikt over hvordan koden går fra f.eks. C til assembly og så til maskinkode.

La meg forsøke å forklare her, poenget var aldri å påstå at en utvikler skal "kompilere" hele koden i hodet.

 

En dyktig utvikler som har god forståelse av språk på høynivå og hele veien ned til maskinkode og gjerne mikrokode vil kunne skrive kode i høyere språk enn maskinkode mer effektivt. F.eks. hvis en programmerer vet hvordan kodestrukturene vil gå fra hans C, C++ eller objective C-kode til CPUen og vil derfor kunne skrive bedre kode og derav mindre bugs. I C#-kode og ennå mer i Java-kode er det vanskelig å vite hvordan koden faktisk vil kjøre. Da er det mer krevende å forsikre seg om at egenprodusert kode ikke får uante konsekvenser. I tillegg blir det verre av at JRE finnes i så utrolig mange varianter og versjoner.

 

Noen ting som f.eks. minnehåndtering blir riktig nok "enklere" i høyere nivås språk, men innkapsling kan virkelig bli komplisert og medføre utrolig mye mer kode og abstraksjoner for å få til relativt enkle ting. Hvis du skal gjøre interaksjon med mange instanser av en klasse blir det også vanskelig å få til dette uten mye ekstra styr, eller hvis du skal lage effektive algoritmer, da innser du hvor genialt f.eks. pekeraritmetikk er. Selve logikken i koden blir cirka den samme i størrelse, og den er ikke nødvendigvis mye enklere eller vanskeligere i det ene eller andre språket. F.eks. i Java blir koden utenom logikken ofte stor(se under). Forskjellen her blir at utvikleren lettere kan vite hvordan logikken faktisk vil kjøre, de øvrige nybegynnerfeilene blir nettopp nybegynnerfeil, og mindre relevant for både høyt og lavt nivå(i denne konteksten C). Kompilert kode gir utvikleren mer kontroll, og utvikleren får nytte av ekstra kunnskap om lavere nivå selv om han skriver i C++. Det er ikke enklere å skrive feilfri logikk til høyere nivå det er.

 

Enkelte påstår at det er så lett å skrive en * eller & feil i et C-program og ødelegge hele greiene, men det er en myte siden et program med en slik feil vil ikke tilsynelatende fungere i unittesting og så plutselig feile pga. dereferering, dessuten elimineres de fleste slike feil ved kompilering.

 

Når alt dette er sagt så finnes det mer elegante objektorienteringer enn C++, og forsåvidt Java. Min favoritt er ObjectPascal som er enkelt og elegant.

Ett enkelt "Hello, World!" program i C inneholder over en million tegn etter preprosessoren er ferdig, dermed skal det gjøres om til assembly, som er øker denne størelsen betraktelig.

Bare for å korrigere; jeg kompilerte nettopp hello world i gcc til 64-bit under Linux, total størrelse er 8.4 kB, og er bare noen få linjer mer med assembly enn uten en eneste kodelinje. Hva er resten? Metadata og headere. Rett skal være rett, uten at jeg vil gjøre noe poeng ut av dette.

 

Det er veldig lite ett språk kan gjøre for å forhindre at en utvikler bryter med språkets paradigme. Det er ikke noe problem å programmere funksjonelt i ett objekt-orientert språk eller omvent. Paradigme er heller ingen regel, mer enn metodikk å jobbe på.

Poenget ditt var at høyere nivås språk skulle være sikrere, men hva er det som gjør f.eks. Java-kode automatisk sikrere enn C-kode? Programmeringsparadigmer er ofte det som trekkes frem som virkemiddel, hvor objektorientering er et godt eksempel her. Objektorientering er egentlig mer et prinsipp som skal "sikre" at utvikleren gjør gode designvalg, men hvordan kan utvikleren få disse fordelene uten å forstå prinsippet? Hvis en dyktig utvikler i Java, PHP eller C++ får godt utbytte av et slikt design så er det på grunn av nettopp designet og ikke programmeringsspråket. Hvis jeg velger dette paradigmet for et prosjekt så er det fordi jeg har overveid fordeler og ulemper, og hvis jeg gjør et objektorientert design må jeg kjenne til hvordan det fungerer for å gjøre det korrekt (enten jeg velger det selv eller får det i oppdrag). Jeg er skremt over hvor mange som tror objektorientert programmering er bruk av objekter, eller tenker det som synonymt med programmering. Selv foreleser i objektorientert programmering klarte ikke å forklare det ved NTNU.

 

MVC i seg selv har ikke synkroniseringsproblemer, det er ett mønster, en måte å strukturere kode på. Det er godt mulig at koden enkelte skriver har synkroniseringsproblemer, det er faktisk ganske vanlig at kode som inneholder flere tråder er vanskelig å få til riktig i ganske mange språk.

Poenget mitt her er at MVC i seg selv er ikke "thread safe"(nok et uttrykk som er misbrukt), dette må gjøres riktig i implementasjon. Den vanligste konsekvensen er at ikke alle trykk på knapper ikke blir registrert. Threading er definitivt en svak side for Java. F.eks. Qt(C++) får dette til bedre.

Det er mange høynivå språk som benytter seg av en garbage collector, og ikke lar deg leke direkte med minnepekere. Grunnen til dette er at minnekorrupsjon, buffer- og stack-overflows er ganske vanlig i språk som gir deg tilgang på dette. Språk som Java, C#, Javascript er derfor sikrere, ifølge din egen definisjon, da de ikke tillater utvikleren å skyte seg i foten ved å leke med minnepekere, eller opprette minnelekasjer ved å glemme å frigjøre minne.

Hvis du har en garbage collector (søppelinnsamler) som lekker minne og frigjør minne tidlig, så har du en garbage collector som ikke fungerer.

<klipp>

Det er ikke sikkert at dataen sier ifra hvis du gjør en feil (iterer forbi lengden av en array for eksempel), noe Java ville ha gjort. Java, og lignende språk, legger en del begrensninger på brukeren nettopp for å gjøre det vanskeligere for brukeren å ødelegge for seg selv.

Som nevnt over, at utviklere bruker pekere feil og skaper sikkerhetsproblemer er en myte (se over).

 

Jeg er enig i at det er en defekt garbage collector, hvilket ikke er uvanlig at oppstår under testing på ulike maskiner med ulike JRE-versjoner, maskinvare, osv. NullPointerException er ikke så uvanlig. Eventuelle feil må håndteres enten det er C eller Java, uten at du påstår akkurat det, at det kastes Exceptions betyr ikke at ting er sikkert. Hvis du bruker arrays i C så er det opp til programmereren å bruke eller lage komponenter som hånterer lengde osv. Dette gjelder også Java.

 

En av de store fordelene med språk som kjører i en virtuell maskin som Java, er at hvis ett sikkerhetshull blir tettet i den virtuelle maskinen (JRE for eksempel) så vil dette hullet være tettet for alle Java-programmer. Dette får du ikke med programmer skrevet i C og C++.

Jevnt over er vel sikkerhet i JVM et problem kontra en fordel for programvare. Hvis jeg skal lage et program så er det skremmende at folk som kjører det har ulike JRE, med ulike JVM med potensielt forskjellig minneallokering. Ulike versjoner gjør det ennå verre for meg å kvalitetssikre min egen programvare.

 

Om du mener virtuelle maskiner er generelt en god idé, fremfor at Javas virtuelle maskiner er ideelle, så står du selvsagt fritt til å mene det.

 

Jeg tror du skal være forsiktig med å påstå at jeg ikke vet hva jeg snakker om her. Merk at jeg ikke sier at et språk er universelt bedre enn et annet, jeg sier heller ikke at høyere nivås språk ikke er hensiktsmessig i noen sammenhenger. Det jeg derimot påpeker er at høyere nivås språk ikke automatisk gjør kode sikrere.

Tja, tror det er lenge siden selve språket javascript var ett problem for noen av disse nettleserne. Mange av sikkerhets-problemene med nettleserne (og da snakker vi sikkerhet som i security) er hovedsaklig relatert til sandboksen javascript kjører i. Javascript er vel egentlig mer sikkert enn eksempelvis Flash og Java, da det er lettere å forhindre javascript i å gjøre noe ulovelig enn å forhindre en plugin.

Hvis du husker Firefox rundt versjon 2 og 3 så var kritiske feil nesten utelukkende tilknyttet Javascript. Fremdeles er Javascript en betydelig kilde til problemer. Alle feilene jeg har sett har vært tilknyttet implementasjonene, ikke spesifikasjonen av språket (så ikke tro at jeg angriper språket). Du må gjerne komme med hvorfor Javascript i nettlesere er tryggere enn Flash-plugins og JRE. Det jeg kan komme på er at nettleseren da kan i det minste ha kontroll over den virtuelle maskinen, på godt og vondt. Litt på sidelinjen av dette så kommer faktisk sikkerhet i operativsystemet inn, både sikkerhet i brukersystem og i rettighetsavgrensning som Linux gjør gjennom AppArmor og Selinux.

Lenke til kommentar

Båndbreddekostnad: 0.12 * 1000 * 5.84 = 700 kr

Kostnad for VPS/server: ....

Så du må altså tjene minimum (700 + k) / 10.000 per kunde i reklameinntekter eller annet. Reklameinntekter alene vil kanskje være noe optimistisk med mindre spillet brukes iherdig. Jeg har aldri sagt at det er umulig, men båndbredde blir fort betydelig med mange TB i måneden, da må inntektene forutsigbart passere dette. (ikke at jeg ser noe poeng å kverulere over dette noe mer)

 

Du kan ikke seriøst mene at båndbreddekrav for et nettbasert spill på noen som helst måte skal kunne overgå båndbreddebruken til et vanlig, lokallagret spill?! HTML5, f.eks., har et disklagrings-API, så det er ikke slik at man eventuelt må laste ned spillet på nytt hver gang man skal spille det. Med andre ord har man i verste fall båndbreddebruk som tilsvarer alle de spillene Steam, Origin osv. tilbyr. Argumentet ditt her er enten veldig klønete formulert (slik at jeg har misforstått deg), eller helt borti natta.

 

 

Noen ting som f.eks. minnehåndtering blir riktig nok "enklere" i høyere nivås språk, men innkapsling kan virkelig bli komplisert og medføre utrolig mye mer kode og abstraksjoner for å få til relativt enkle ting. Hvis du skal gjøre interaksjon med mange instanser av en klasse blir det også vanskelig å få til dette uten mye ekstra styr, eller hvis du skal lage effektive algoritmer, da innser du hvor genialt f.eks. pekeraritmetikk er. Selve logikken i koden blir cirka den samme i størrelse, og den er ikke nødvendigvis mye enklere eller vanskeligere i det ene eller andre språket.

 

Quicksort i Haskell:

 

 

quicksort [] = []
quicksort (p:xs) = (filter (< p) xs) ++ [p] ++ (filter (>= p) xs)

 

 

 

Quicksort i C:

 

 

void qsort(int a[], int lo, int hi)
{
 int h, l, p, t;
 if (lo < hi) {
l = lo;
h = hi;
p = a[hi];
do {
  while ((l < h) && (a[l] <= p))
	  l = l+1;
  while ((h > l) && (a[h] >= p))
	  h = h-1;
  if (l < h) {
	  t = a[l];
	  a[l] = a[h];
	  a[h] = t;
  }
} while (l < h);
a[hi] = a[l];
a[l] = p;
qsort( a, lo, l-1 );
qsort( a, l+1, hi );
 }
}

 

 

 

Jeg vet ikke med deg, men jeg vil si at Haskell-varianten både er mye lettere å lese, samt mye mindre i størrelse.

 

Enkelte påstår at det er så lett å skrive en * eller & feil i et C-program og ødelegge hele greiene, men det er en myte siden et program med en slik feil vil ikke tilsynelatende fungere i unittesting og så plutselig feile pga. dereferering, dessuten elimineres de fleste slike feil ved kompilering.

 

Dette er ikke riktig. Slike feil kan lett overleve gjennom unittesting. Et typisk eksempel er om du egentlig skal ha en peker til en peker (f.eks. int**), men glemmer en asterisk og heltallet du peker til har en verdi som tilfeldigvis kan fungere som adresse. (Først og fremst er dette sannsynlig dersom 0/NULL er en akseptabel adresse for pekeren.)

 

Som nevnt over, at utviklere bruker pekere feil og skaper sikkerhetsproblemer er en myte.

 

Det er sannsynligvis det dummeste jeg har hørt på lang tid. Jeg sier bare buffer overflow.

 

Jevnt over er vel sikkerhet i JVM et problem kontra en fordel for programvare. Hvis jeg skal lage et program så er det skremmende at folk som kjører det har ulike JRE, med ulike JVM med potensielt forskjellig minneallokering. Ulike versjoner gjør det ennå verre for meg å kvalitetssikre min egen programvare.

 

Mens for C eller C++ er det bare én plattform du har å forholde deg til? Get real.

Lenke til kommentar

Dette er ikke riktig. Slike feil kan lett overleve gjennom unittesting. Et typisk eksempel er om du egentlig skal ha en peker til en peker (f.eks. int**), men glemmer en asterisk og heltallet du peker til har en verdi som tilfeldigvis kan fungere som adresse. (Først og fremst er dette sannsynlig dersom 0/NULL er en akseptabel adresse for pekeren.)

Vis meg gjerne kode der du glemmer en asterisk og det likevel kompilerer. Den eneste lovlige implisitte konverteringen mellom pekere er til void*, og da kun i C. Int kan kun implisitt konverteres til en peker dersom den brukes for å initialisere pekeren.

NULL-pekere er et like stort problem i Java, C# og JavaScript som det er i C og C++.

  • Liker 1
Lenke til kommentar

Båndbreddekostnad: 0.12 * 1000 * 5.84 = 700 kr

Kostnad for VPS/server: ....

Så du må altså tjene minimum (700 + k) / 10.000 per kunde i reklameinntekter eller annet. Reklameinntekter alene vil kanskje være noe optimistisk med mindre spillet brukes iherdig. Jeg har aldri sagt at det er umulig, men båndbredde blir fort betydelig med mange TB i måneden, da må inntektene forutsigbart passere dette. (ikke at jeg ser noe poeng å kverulere over dette noe mer)

 

Med Linode får du 1Tb utgående båndbredde og en helt ok server til prisen til 20$. Dette er brøkdelen av timeslønna til utviklern du må betale. Hvis du ikke har råd til båndbredden og server, så har du ikke råd til å utvikle spillet heller. Hvis du utvikler spillet på egen tid og ikke har råd til å distribuere det, så finnes det mange løsninger idag, Google Play, App Store, Steam, Origin... For HTML5-spill finnes Chrome Web Store per idag.

 

La meg forsøke å forklare her, poenget var aldri å påstå at en utvikler skal "kompilere" hele koden i hodet.

 

En dyktig utvikler som har god forståelse av språk på høynivå og hele veien ned til maskinkode og gjerne mikrokode vil kunne skrive kode i høyere språk enn maskinkode mer effektivt. F.eks. hvis en programmerer vet hvordan kodestrukturene vil gå fra hans C, C++ eller objective C-kode til CPUen og vil derfor kunne skrive bedre kode og derav mindre bugs. I C#-kode og ennå mer i Java-kode er det vanskelig å vite hvordan koden faktisk vil kjøre. Da er det mer krevende å forsikre seg om at egenprodusert kode ikke får uante konsekvenser. I tillegg blir det verre av at JRE finnes i så utrolig mange varianter og versjoner.

 

Å kjenne til hvordan koden din kompileres kan kanskje gjøre deg flinkere til å optimalisere, men hjelper deg fint lite i å unngå bugs.

 

Selvom dette hadde vært ett hjelpemiddel, så er det like enkelt å vite hva slags bytecode Java kompilerer ned til, som å vite hva slags assembly C/C++ kompilerer ned til, muligens også enklere. Java Bytecode er ikke nødvendigvis representativt av hva CPUen faktisk kommer til å kjøre, men du mister også ganske grei oversikt over hva slags assembly som blir produsert av med en gang du skrur på optimalisering under kompilasjon for ikke-VM baserte språk som C/C++. Du har heller ingen garanti for at C/C++ ender opp som samme maskinkode uavhengig av kompilatoren du bruker. Clang, GCC, tinyc kan fint generere forskjellig maskinkode utifra samme kildekode.

 

Noen ting som f.eks. minnehåndtering blir riktig nok "enklere" i høyere nivås språk, men innkapsling kan virkelig bli komplisert og medføre utrolig mye mer kode og abstraksjoner for å få til relativt enkle ting. Hvis du skal gjøre interaksjon med mange instanser av en klasse blir det også vanskelig å få til dette uten mye ekstra styr, eller hvis du skal lage effektive algoritmer, da innser du hvor genialt f.eks. pekeraritmetikk er. Selve logikken i koden blir cirka den samme i størrelse, og den er ikke nødvendigvis mye enklere eller vanskeligere i det ene eller andre språket. F.eks. i Java blir koden utenom logikken ofte stor(se under). Forskjellen her blir at utvikleren lettere kan vite hvordan logikken faktisk vil kjøre, de øvrige nybegynnerfeilene blir nettopp nybegynnerfeil, og mindre relevant for både høyt og lavt nivå(i denne konteksten C). Kompilert kode gir utvikleren mer kontroll, og utvikleren får nytte av ekstra kunnskap om lavere nivå selv om han skriver i C++. Det er ikke enklere å skrive feilfri logikk til høyere nivå det er.

 

Utsagn som dette er hvorfor jeg tidligere hintet til at du ikke visste hva du snakker om. Du bruker innkapsling i samme setning som minnehåndtering, selv om de ikke har noe med hverandre å gjøre. Innkapsling er ett begrep som brukes i objektorienterte programmer for å beskrive det å skjule medlemsvariabler i en klasse, og gi de beskyttet tilgang via getter/setter metoder/funksjoner/medlemsfunksjoner. Garbage collection eller minnehåndtering generelt har dog ingenting med objektorientering å gjøre.

 

Når du skriver at innkapsling fører til mer flere abstraksjoner så er det også ett lite varsku. Abstraksjoner er selve poenget til at objektorientering ble populært, siden det blant annet tilater polymorfi og øker muligheten for kode-gjennbruk. Dette fører gjerne til mindre kode totalt sett.

 

Kompilert kode gir deg ikke nødvendigvis mer kontroll (her regner jeg med at du mener kode kompilert til maskinkode, Java må også kompileres før det kjøres, men da til bytecode og ikke direkte til maskinkode). Det finnes prosjekter som kompilerer Java direkte til maskinkode, du får ikke mer kontroll på noe som helst vis av den grunn. Det finnes også en god del språk som er mer høynivå enn Java som også kompilerer til maskinkode. Haskell er her ett godt eksempel.

 

Selv om det er fullt mulig å skrive kode med masse feil selv i høynivå språk, så vil du nok i de fleste tilfeller ha mindre bugs jo høyere nivå du programmerer på. Grunnen til dette er at du som utvikler ikke trenger å tenke på like mange variabler. Det er mange feil tilknyttet minnehåndtering i C og C++ utviklede programmer, det er veldig sjelden du har feil tilknyttet minnehåndtering i Java, enkelt og greit fordi du ikke står for minnehåndteringen i Java. Du kan derfor fokusere deg på problemet du skal løse, uten å måtte bry deg om minnehåndtering i tillegg... Økt fokus på ett problem, øker sannsynligheten for at du implementerer det riktig første gangen.

 

Bare for å korrigere; jeg kompilerte nettopp hello world i gcc til 64-bit under Linux, total størrelse er 8.4 kB, og er bare noen få linjer mer med assembly enn uten en eneste kodelinje. Hva er resten? Metadata og headere. Rett skal være rett, uten at jeg vil gjøre noe poeng ut av dette.

 

Her har du helt rett, og jeg burde tenkte meg nøyere om før jeg utalte meg.

 

Poenget ditt var at høyere nivås språk skulle være sikrere, men hva er det som gjør f.eks. Java-kode automatisk sikrere enn C-kode? Programmeringsparadigmer er ofte det som trekkes frem som virkemiddel, hvor objektorientering er et godt eksempel her. Objektorientering er egentlig mer et prinsipp som skal "sikre" at utvikleren gjør gode designvalg, men hvordan kan utvikleren få disse fordelene uten å forstå prinsippet? Hvis en dyktig utvikler i Java, PHP eller C++ får godt utbytte av et slikt design så er det på grunn av nettopp designet og ikke programmeringsspråket. Hvis jeg velger dette paradigmet for et prosjekt så er det fordi jeg har overveid fordeler og ulemper, og hvis jeg gjør et objektorientert design må jeg kjenne til hvordan det fungerer for å gjøre det korrekt (enten jeg velger det selv eller får det i oppdrag). Jeg er skremt over hvor mange som tror objektorientert programmering er bruk av objekter, eller tenker det som synonymt med programmering. Selv foreleser i objektorientert programmering klarte ikke å forklare det ved NTNU.

 

Programmeringsparadigme er en måte å programmere på, det skal ikke sikre noe som helst. Det har heller ingenting med sikkerhet å gjøre, og jeg skjønner ikke hvorfor du drar det inn i diskusjonen, spesielt siden du sammenligner ett objektorientert språk (Java) med ett imperativt språk ©.

 

Objektorientert programmering går jo ut på å abstrahere problemer inn i klasser/objekter... Det ligger litt i navnet. Hva skal objektorientert programmering handle om hvis ikke objekter står i fokus? Det er ikke synonymt med programmering, det har du helt rett i, men bruk av objekter er ganske sentralt i den måten å programmere på.

 

Poenget mitt her er at MVC i seg selv er ikke "thread safe"(nok et uttrykk som er misbrukt), dette må gjøres riktig i implementasjon. Den vanligste konsekvensen er at ikke alle trykk på knapper ikke blir registrert. Threading er definitivt en svak side for Java. F.eks. Qt(C++) får dette til bedre.

 

Jeg skjønner ikke hvorfor du drar opp MVC og "thread safe" i samme setning. De har ingen verdens ting med hverandre å gjøre. Førstnevnte er ett mønster for strukturering av UI-kode. Sistnevnte er ett begrep som beskriver at to tråder kan manipulere samme gjenstand uten at det skaper problemer. Dette igjen har heller ingenting med input (knapper som blir registrert) å gjøre. I Javascript håndteres eksempelvis input helt uten tråder.

 

Tråder er faktisk implementert i Java i motsetning til C++ (har riktignok blitt implementert i C++11) hvor du må ty til tredjeparts biblioteker. Å jobbe med tråder, semaforer, låser osv. er langt ifra en enkel oppgave når du får litt kompleksitet inn i bildet. Det er derfor andre fremgangsmåter som eksempelvis Actors er enklere å jobbe med, og å foretrekke. Når det er nevnt så finnes det ett tredjeparts bibliotek til Java og JVM-baserte språk som heter Akka, som er en actors implementasjon. Med Akka er threading plutselig barnemat i Java, og det finnes sikkert en actor implementasjon for C++ også.

 

Jeg er enig i at det er en defekt garbage collector, hvilket ikke er uvanlig at oppstår under testing på ulike maskiner med ulike JRE-versjoner, maskinvare, osv. NullPointerException er ikke så uvanlig. Eventuelle feil må håndteres enten det er C eller Java, uten at du påstår akkurat det, at det kastes Exceptions betyr ikke at ting er sikkert. Hvis du bruker arrays i C så er det opp til programmereren å bruke eller lage komponenter som hånterer lengde osv. Dette gjelder også Java.

 

Med tanke på at en JRE (Java Runtime) skal fungere likt uavhengig maskinen den kjører på for å følge enn gitt versjon av standarden, så er veldig uvanlig at du opplever annerledes oppførsel fra maskin til maskin. Hvis du kjører kode på en JRE med defekt garbage collector så oppfordrer jeg deg til å bytte til en stabil JRE, for eksempel den offisielle? Med tanke på hvor mange som bruker Java i kritiske applikasjoner så ville du hørt ramaskrik dersom garbage collectoren faktisk var defekt.

 

Derefereing av null pekere er ganske vanlig i C++ og Java, det har fortsatt ingenting med sikkerhet eller garbage collection å gjøre.

 

Selve det at det kastes exceptions betyr ikke at ting er sikkert nei, det stemmer. Når Java kaster exceptions som gjør meg klar over feil i koden min som C++ ikke varsler om derimot, så blir Java mer sikkert. Hvis jeg korrupterer minne i en C++ applikasjon, så vil applikasjonen i beste fall kræsje. I verste fall vil koden fortsette å kjøre som om ingenting galt er skjedd. Og det kan ta flere måneder før feilen blir åpenbar. Når Java eliminerer feil relatert til minnekorrupsjon, ved å eliminere peker aritmetikk og kaste exceptions uansett når jeg gjør noe galt, så blir Java ett mer sikkert miljø for meg å jobbe i.

 

Det jeg derimot påpeker er at høyere nivås språk ikke automatisk gjør kode sikrere.

 

Helt riktig.

 

Hvis du husker Firefox rundt versjon 2 og 3 så var kritiske feil nesten utelukkende tilknyttet Javascript. Fremdeles er Javascript en betydelig kilde til problemer. Alle feilene jeg har sett har vært tilknyttet implementasjonene, ikke spesifikasjonen av språket (så ikke tro at jeg angriper språket). Du må gjerne komme med hvorfor Javascript i nettlesere er tryggere enn Flash-plugins og JRE. Det jeg kan komme på er at nettleseren da kan i det minste ha kontroll over den virtuelle maskinen, på godt og vondt. Litt på sidelinjen av dette så kommer faktisk sikkerhet i operativsystemet inn, både sikkerhet i brukersystem og i rettighetsavgrensning som Linux gjør gjennom AppArmor og Selinux.

 

Det var ikke utelukket tilknyttet javascript, og det er det fortsatt ikke, det er tilknyttet smutthull i sandboksen javascript opererer i. Forskjeller i måten javascript fungerer på, implementasjon, kan føre til bugs som er ett irritasjonsmoment for utvikleren. Det er likevel fortsatt sandboksen som bestemmer hva javscript har mulighet til å manipulere, som er uavhengig av språk-implementasjon.

 

Javascript er sikrere så i måte enn Flash og Java for nettleseseren (de to siste ordene er viktig) da nettleseren kan ha full kontroll over hva javascript driver med. Hvis du sender informasjon til en java-plugin, så har den java-pluginen mulighet til å videresende den informasjon til hvilken som helst server i verden uten at nettleseren kan forhindre dette. I de fleste nettlesere idag har ikke javascript lov å sende informasjon andre steder enn til nettsiden du foreløpig er koblet til, noe som gjør javascript sikrerere enn java-pluginen.

 

Selinux og AppArmor ville ikke beskyttet meg i forrige eksempel...

Lenke til kommentar

Å kjenne til hvordan koden din kompileres kan kanskje gjøre deg flinkere til å optimalisere, men hjelper deg fint lite i å unngå bugs.

En utvikler som forstår hvordan koden han skriver i et bestemt språk faktisk vil kjøre på CPUen vil kunne skrive bedre kode, og vil dermed kunne lettere oppdage feil i eget design. Dette er lettere med kompilerte språk som ikke er av for høyt nivå. Dette hjelper selvsagt med ytelse, men vil også redusere faren for defekte design.

 

Noen ting som f.eks. minnehåndtering blir riktig nok "enklere" i høyere nivås språk, men innkapsling kan virkelig bli komplisert og medføre utrolig mye mer kode og abstraksjoner for å få til relativt enkle ting.

Utsagn som dette er hvorfor jeg tidligere hintet til at du ikke visste hva du snakker om. Du bruker innkapsling i samme setning som minnehåndtering, selv om de ikke har noe med hverandre å gjøre.

<klipp>

Garbage collection eller minnehåndtering generelt har dog ingenting med objektorientering å gjøre.

Hvis du faktisk leser hva jeg skrev så har jeg ikke sagt at disse tingene har noe som helst med hverandre å gjøre. Må du virkelig komme med falske påstander for å "bevise" hvor kunnskapsløs jeg er?

 

Påstanden din er at høyere nivås språk er sikrere, jeg argumenterer hvorfor de sidene ved høyere nivås språk som typisk trekkes frem ikke automatisk gir sikkerhet slik det typisk hevdes, og hvis jeg gjør noe feil i min argumentasjon så må du påpeke det fremfor å angripe person.

 

Innkapsling er en sentral del av paradigmet objektorientering som f.eks. er sterkt knyttet til Java. Tanken er at innkapslingen skal være med på å sikre at data blir aksessert, initialisert og frigjort på riktig måte, pluss at "logikken" som behandler dataen blir plassert på riktig plass i klassehierarkiet. Dette skal altså være "safety" for å hjelpe til å lage bedre design, men for at den skal ha noe virkning så må det implementeres riktig av programmereren, og for å gjøre dette riktig må vedkommende forstå hva objektorientering er. At språket er Java kontra f.eks. C her gjør ikke at dette automatisk blir sikrere, det er poenget mitt. Å lage et robust, effektivt og kompakt objektorientert design er en krevende oppgave, og det er veldig fort å gjøre ting for komplisert.

 

Selve det at det kastes exceptions betyr ikke at ting er sikkert nei, det stemmer. Når Java kaster exceptions som gjør meg klar over feil i koden min som C++ ikke varsler om derimot, så blir Java mer sikkert. Hvis jeg korrupterer minne i en C++ applikasjon, så vil applikasjonen i beste fall kræsje. I verste fall vil koden fortsette å kjøre som om ingenting galt er skjedd. Og det kan ta flere måneder før feilen blir åpenbar. Når Java eliminerer feil relatert til minnekorrupsjon, ved å eliminere peker aritmetikk og kaste exceptions uansett når jeg gjør noe galt, så blir Java ett mer sikkert miljø for meg å jobbe i.

Som sagt er det en myte at minnehåndtering i C og C++ er vanskelig, og selv om feil peker-bruk i noen tilfeller vil kompilere, så vil ikke koden i grundige tester oppføre seg "korrekt" og så plutselig slutte med å fungere fordi symbolet på en peker er feil. Det er heller ikke vanskelig å debugge slik kode, du kan slå på debug-symboler, du kan ta stack trace, og når ting går galt så får du ikke bare en kryptisk segfault. Og når det er sagt så kan mystiske feil absolutt inntreffe i Java, NullPointerExceptions og lignende som kan se ut som de kommer fra runtimes på stacktracen, men som kanskje egentlig er forårsaket av egen kode et annet sted. At du har hatt en dårlig erfaring blir for dårlig grunnlag til å skape en anekdote. På samme måte kunne jeg skapt min egen anekdote basert på all ustabilitet og alle problemer med Java, C#/.Net osv, men la oss være voksne og seriøse.

 

Selv om det er fullt mulig å skrive kode med masse feil selv i høynivå språk, så vil du nok i de fleste tilfeller ha mindre bugs jo høyere nivå du programmerer på. Grunnen til dette er at du som utvikler ikke trenger å tenke på like mange variabler.

Jeg er veldig spent på hvilket grunnlag dette er basert på. Jeg vet at det er en opplest "sannhet" som mange forelesere bruker, men jeg har til gode å se noen utdype det eller legitimere det. Er et basert på den store overveldende mengden krevende kvalitetsprogramvare som er basert på slike språk? Slik som tunge bildebehandlere, CAD, videoredigering osv. ? Eller sikter du mer til hobbyprogrammer? Siden vi snakker om spill her, tenk over hvilke tekniske krav spill som er implementert i f.eks. Java typisk har, kontra mer krevende spill?

 

Det er mange feil tilknyttet minnehåndtering i C og C++ utviklede programmer, det er veldig sjelden du har feil tilknyttet minnehåndtering i Java, enkelt og greit fordi du ikke står for minnehåndteringen i Java. Du kan derfor fokusere deg på problemet du skal løse, uten å måtte bry deg om minnehåndtering i tillegg... Økt fokus på ett problem, øker sannsynligheten for at du implementerer det riktig første gangen.

Nok en gang, har du statistikk, gode oversikter eller er det anedokter på gang? Du får det til å høre ut som at utvikling i slike språk er som en lek sammenlignet med lavere språk. Det vil ikke gå særlig bra hvis utviklere har en slik nærmest ignorant holdning til utvikling, som sagt er feilhåndtering en minst like viktig og stor oppgave i f.eks. Java.

 

Jeg skjønner ikke hvorfor du drar opp MVC og "thread safe" i samme setning. De har ingen verdens ting med hverandre å gjøre. Førstnevnte er ett mønster for strukturering av UI-kode. Sistnevnte er ett begrep som beskriver at to tråder kan manipulere samme gjenstand uten at det skaper problemer. Dette igjen har heller ingenting med input (knapper som blir registrert) å gjøre. I Javascript håndteres eksempelvis input helt uten tråder.

Så la meg opplyse deg :)

Hvis du har et middels komplekst GUI i MVC-struktur så har du gjerne en rekke lyttere (implementert som threads som sitter og lytter på input), og du ønsker selvsagt å prosessere interaksjoner uten at et tastetrykk ikke blir registert. Husk at vi snakker om spill her (ref. tittel på diskusjonen), og i spill blir synkronisering helt kritisk. Som du vet har spill en "game loop" som f.eks. går 60 ganger i sekundet, i tillegg må input registreres og spillet må rendres i en konsistent tilstand. Samme hvilken struktur som velges (MVC eller ei) så blir synkronisering kritisk. Låser og lignende i f.eks. Java blir for upresist til å få til jevn flyt i et spill, dette er selv en utfordring i C, så spill kan gjerne bruke teknikker som låsfrie køer for å forbedre flyten.

 

-----

Så Robin, hvis jeg og de andre her har så lite peiling om hvorfor høynivåsspråk er så mye sikrere så burde du benytte anledningen til å forklare oss hvorfor, jeg venter fremdeles på en god forklaring. Hvis der er overveldende fordeler som jeg eller andre ikke er klar over så burde det være en smal sak å vise.

Lenke til kommentar

En utvikler som forstår hvordan koden han skriver i et bestemt språk faktisk vil kjøre på CPUen vil kunne skrive bedre kode, og vil dermed kunne lettere oppdage feil i eget design. Dette er lettere med kompilerte språk som ikke er av for høyt nivå. Dette hjelper selvsagt med ytelse, men vil også redusere faren for defekte design.

 

Poenget mitt er at det er tilnærmet umulig å vite hvordan koden din vil kjøre på CPUen. Forskjellige kompilere vil gi forskjellige kode, hvilket optimaliseringsnivå, eventuelt om du skal kompilere med debug symboler, vil gi forskjellig kode. Når det er sagt så er det ganske mange som har en god forståelse av hvordan språk som f.eks. javascript kompileres til maskinkode. Google har hatt en rekke talks om hvordan V8 motoren kompilerer kode, og hvordan du skal skrive javascript kode som kjører mest effektivt på V8. Du vil ikke få mindre bugs, men med den forståelsen kan du skrive kode som er mer effektiv.

 

I min erfaring, så drives design mer av hva du trenger å få til, og hvordan du kan få til dette med minst mulige linjer uten å miste lesbarhet og fleksibilitet. Ikke hva koden din kompileres ned til. Hva koden kompileres ned til er egentlig lykegyldig så lenge koden er lett å lese, oversiktlig og fungerer. Trenger du ytelse så kan kunnskap om hva CPUen faktisk gjør for at koden din skal fungere faktisk hjelpe, men ellers er det mer eller mindre irrelevant.

 

Hvis du faktisk leser hva jeg skrev så har jeg ikke sagt at disse tingene har noe som helst med hverandre å gjøre. Må du virkelig komme med falske påstander for å "bevise" hvor kunnskapsløs jeg er?

 

Jeg leste hva du skrev, og trekker en logisk konklusjon om at når du sier "automatisk minnehåndtering gjør ting enklere, men innkapsling kan gjøre ting mer komplisert og føre til mer kode" at du mener de to tingene har noe med hverandre å gjøre. Det er ikke meningen å henge deg ut, men det er vanskelig å forstå hva du mener.

 

Hvis du leste det jeg skrev, så ser du også at jeg allerede har prøvd å forklare dette.

 

Dette er hvordan jeg ville formulert din setning:

Høyere nivå språk har ofte implementert en form for automatisk minnehåndtering, som naturligvis gjør minnehåndtering enklere på bekostning av ytelse når man allokerer mye minne. Høyere nivå språk har også en tendens til å være objektorienterte, som i min mening kan føre til mer invikla kode selv for enkle oppgaver.

 

Påstanden din er at høyere nivås språk er sikrere, jeg argumenterer hvorfor de sidene ved høyere nivås språk som typisk trekkes frem ikke automatisk gir sikkerhet slik det typisk hevdes, og hvis jeg gjør noe feil i min argumentasjon så må du påpeke det fremfor å angripe person.

 

Innkapsling er en sentral del av paradigmet objektorientering som f.eks. er sterkt knyttet til Java. Tanken er at innkapslingen skal være med på å sikre at data blir aksessert, initialisert og frigjort på riktig måte, pluss at "logikken" som behandler dataen blir plassert på riktig plass i klassehierarkiet. Dette skal altså være "safety" for å hjelpe til å lage bedre design, men for at den skal ha noe virkning så må det implementeres riktig av programmereren, og for å gjøre dette riktig må vedkommende forstå hva objektorientering er. At språket er Java kontra f.eks. C her gjør ikke at dette automatisk blir sikrere, det er poenget mitt. Å lage et robust, effektivt og kompakt objektorientert design er en krevende oppgave, og det er veldig fort å gjøre ting for komplisert.

 

En av påstandene mine har vært at eksempelvis Java ikke støtter en rekke operasjoner (peker-aritmetikk og manuell minnehåndtering) som forhindrer feil som minnelekasjer (fortsått åpen for space-leaks) og minnekorrupsjon. Det gjør Java sikrere enn eksempelvis C hvor dette er fullt mulig. Det har ikke noe å si hvor vanskelig det er å ha kontroll på dette i C. Det er fortsatt mulig, og selv de beste programmererne driter seg ut fra tid til annen.

 

Jeg er også uenig med deg i at design, og implementasjon av design har noe med "safety" å gjøre (og hvis jeg har misforstått deg her, les teksten din igjen, den er isåfall lett å misforstå). Du sier, om jeg forstår riktig, at du må kunne vite hva objektorientering er for å kunne implementere ett godt design som gir "safety", uansett om språket er C eller Java. Men vil ikke Java da uansett være sikrere for objektorienterte programmer da Java faktisk er objektorientert og C ikke er det? Du må selvfølgelig vurdere språk etter paradigme, men hvis objektorientering er det paradigme du vil følge så må det jo, etter din egen definisjon, være mer sikkert å lage dette programmet i ett språk som faktisk er objektorientert?

 

 

Som sagt er det en myte at minnehåndtering i C og C++ er vanskelig, og selv om feil peker-bruk i noen tilfeller vil kompilere, så vil ikke koden i grundige tester oppføre seg "korrekt" og så plutselig slutte med å fungere fordi symbolet på en peker er feil. Det er heller ikke vanskelig å debugge slik kode, du kan slå på debug-symboler, du kan ta stack trace, og når ting går galt så får du ikke bare en kryptisk segfault. Og når det er sagt så kan mystiske feil absolutt inntreffe i Java, NullPointerExceptions og lignende som kan se ut som de kommer fra runtimes på stacktracen, men som kanskje egentlig er forårsaket av egen kode et annet sted. At du har hatt en dårlig erfaring blir for dårlig grunnlag til å skape en anekdote. På samme måte kunne jeg skapt min egen anekdote basert på all ustabilitet og alle problemer med Java, C#/.Net osv, men la oss være voksne og seriøse.

 

Konseptet bak minnehåndtering i C og C++ er ikke vanskelig å forstå, eller programmere. Regelen er at mest mulig skal legges på stacken, og når det ikke er mulig så bruker du malloc() og free() i C, new/new[] og delete/delete[] i C++. Det er derimot veldig enkelt å gjøre det feil uten at kompilator, eller noen test sier ifra. Minnelekasjer er med andre ord enkelt, såpass enkelt at selv de beste har minnelekasjer i sine programmer.

 

Det kan godt hende at kode som kompilerer fint, også fungerer fint i tester, men kræsjer helt random i praksis. På jobb hadde vi kode hvor resultatet av enkel peker-aritmetikk fikk en peker til å peke forbi lengden av en array. Dette gikk helt fint på maskinen vi i utgangspunktet testet på, for der var av en eller annen grunn alltid dette feltet i minnet satt til 0. På en annen maskin ville dette kræsje en gang i blant, avhengig av hva den pekeren refererte til. Nei, det var ikke vanskelig å finne feilen, og det var heller ikke vanskelig å fikse (i akkurat det tilfellet), men det er fortsatt tid en Java-utvikler hadde brukt på andre ting fordi den type bugs ikke er mulig i Java.

 

De feilene som kan inntreffe i Java kan og intreffe i språk som kompilerer til maskinkode og. Forskjellen er at Java har mindre feil som kan inntreffe, fordi enkelte feil som kan oppstå i C++ ikke er mulig å gjennskape i Java.

 

Igjen formulerer du deg litt dårlig når du sier at "som kan se ut som de kommer fra runtimes på stacktracen". Når du sier runtimes så regner jeg her med at du sikter til den virtuelle maskinen (jeg kaller deg ikke uvitende, det er folk som sier runtime og virtuell machine om hverandre, jeg ville bare stadfeste at det er det jeg går utifra at du mener). Jeg regner også med at den ekstra s-en er en skrivefeil fordi java-kode kjører alltid i èn virtuell maskin om gangen. Dersom det hadde vært en feil i den virtuelle maskinen, så ville du kun merket det dersom koden gjorde noe den ikke skulle gjøre. Siden Java er såpass modent er det nok ikke sannsynlig at det er dette du sikter til. Jeg regner med at du sikter til at feil kan oppstå i Java sitt standardbibliotek. Dette kan like fullt oppstå i standardbiblioteket til C og/eller C++ også, det er ikke noe nytt. Det å dereferere NULL-pekere er og ett like stort problem i C++ som det er i Java, selv om jeg liker bedre at Java har en egen type kalt "null" istedenfor at det er en macro som evalueres til (void*)0 i C og C++.

 

Min egen erfaring med språket etter å ha jobbet med det i snart ett år er alt jeg har å gå fra. I min mening hadde det vært en god del værre hvis jeg bare gjennfortalte problemene til noen andre.

 

Jeg er veldig spent på hvilket grunnlag dette er basert på. Jeg vet at det er en opplest "sannhet" som mange forelesere bruker, men jeg har til gode å se noen utdype det eller legitimere det. Er et basert på den store overveldende mengden krevende kvalitetsprogramvare som er basert på slike språk? Slik som tunge bildebehandlere, CAD, videoredigering osv. ? Eller sikter du mer til hobbyprogrammer? Siden vi snakker om spill her, tenk over hvilke tekniske krav spill som er implementert i f.eks. Java typisk har, kontra mer krevende spill?

 

Grunnlaget jeg har for påstanden skriver jeg jo i setningen etter. Det at utviklere har mindre variabler å tenke på. La meg forklare nærmere. La oss ta for oss Erlang denne gangen. I erlang trenger jeg ikke tenke over minnehåndtering. Erlang gjør det for meg. Jeg trenger heller ikke bry meg om locks, mutexes, semaphores eller tråder. Erlang tvinger meg til å bruke actor-pattern for å håndtere concurrency (som tydeligvis ikke er så dumt da Scala, Go og Rust har gått samme veien). Siden språket er funksjonelt også, så er det ett stort fokus på funksjoner uten side-effekter, som er enkle å teste og gir generelt få overaskelser. Språket er også dynamisk, så jeg trenger ikke definere ting i hytt og pine. I ett slikt språk skriver du mindre kode, det er lettere å ha funksjoner som kun gjør det essensielle (ingen minnehåndtering eller låser og sånt skvip) og som dermed har større potensiale til å være oversiktlige og enkle å lese.

 

Det er også UTROLIG vanlig med høyere nivå språk i spill. Man implementerer vanligvis det som krever mye ytelse eller direkte kontakt med maskinvaren (rendering, shaders osv) i C eller C++, mens logikk, gui og nettverkskode gjerne taes i ett høyere nivå språk som f.eks. Lua. Spill som benytter seg av Lua er blant annet S.T.A.L.K.E.R., World of Warcraft, Mafia 2 og Civilization 5.

 

http://en.wikipedia....ted_video_games

 

Nok en gang, har du statistikk, gode oversikter eller er det anedokter på gang? Du får det til å høre ut som at utvikling i slike språk er som en lek sammenlignet med lavere språk. Det vil ikke gå særlig bra hvis utviklere har en slik nærmest ignorant holdning til utvikling, som sagt er feilhåndtering en minst like viktig og stor oppgave i f.eks. Java.

 

Linka ikke jeg til en blogg tidligere med en som skrev om en C++ bittorrent klient til Erlang og sparte 75% linjer kode? Med avsnittet mitt over i bakhodet så burde jo det bety noe? Har du noen statestikk som sier motsatt?

 

Å jobbe med høyere nivå språk ER en lek sammenlignet med lavere nivå språk. Det er en grunn til at språk som Javascript, Python og Ruby tiltrekker seg flere utviklere enn andre språk. Selv Java er å foretrekke over C/C++ med mindre du virkelig trenger ytelsen. Med tanke på at at Unreal Engine nå kjører i nettlesern med helt ok grafikk burde begynne å bli ett tegn på at de fleste av oss faktisk ikke trenger det.

 

Ja, feilhåndtering er like viktig som i alle andre språk. Når du derimot ikke trenger å håndtere like mye feil og kan skrive mindre kode i ett annet språk uten å offre for mye, så er det ingen grunn til å pines heller.

 

Så la meg opplyse deg :)

Hvis du har et middels komplekst GUI i MVC-struktur så har du gjerne en rekke lyttere (implementert som threads som sitter og lytter på input), og du ønsker selvsagt å prosessere interaksjoner uten at et tastetrykk ikke blir registert. Husk at vi snakker om spill her (ref. tittel på diskusjonen), og i spill blir synkronisering helt kritisk. Som du vet har spill en "game loop" som f.eks. går 60 ganger i sekundet, i tillegg må input registreres og spillet må rendres i en konsistent tilstand. Samme hvilken struktur som velges (MVC eller ei) så blir synkronisering kritisk. Låser og lignende i f.eks. Java blir for upresist til å få til jevn flyt i et spill, dette er selv en utfordring i C, så spill kan gjerne bruke teknikker som låsfrie køer for å forbedre flyten.

 

Du kan fortsatt bruke actors og fortsatt bruke MVC som design for GUI-koden. Hvis du bruker javascript, noe demoen i artikkelen gjør, så har du ikke tilgang på tråder og dermed ikke synkronisering-primitiver som låser og semaforer heller. Dette er grunnen til at jeg ikke skjønner hvorfor du drar inn MVC og tråder i samme setning, de to tingene trenger ikke ha noe med hverandre å gjøre.

 

Litt pirk. En game loop går sannsynligvis ganske mange ganger mer enn 60 ganger i sekundet. Kallet som faktisk tegner det som står på skjermen kan derimot godt bli kalt så sjeldent.

 

Så Robin, hvis jeg og de andre her har så lite peiling om hvorfor høynivåsspråk er så mye sikrere så burde du benytte anledningen til å forklare oss hvorfor, jeg venter fremdeles på en god forklaring. Hvis der er overveldende fordeler som jeg eller andre ikke er klar over så burde det være en smal sak å vise.

 

Jeg har ikke hevet meg over noen andre her. Der jeg har vært uenig har jeg kommentert dette, med begrunnelse, og det har også hovedsaklig vært rettet mot deg. Hvis du har fått inntrykket at jeg prøver å henge deg ut så beklager jeg, det har ikke vært meningen. Det er derimot tydeligvis veldig enkelt å misforstå noe av det du skriver til den grad at det kan virke som om du ikke vet hva du snakker om.

 

Jeg har nevnt det flere ganger allerede, men grunnene til at høyere nivå språk er sikrere har med at de eliminerer feil som er lett å gjøre og KAN VÆRE vanskelig å oppdage og rette i språk som er av lavere nivå. Eksempler på dette er minnekorrupsjon og race-conditions. Når du i tillegg vanligvis skriver færre linjer i høyere nivå språk, så blir det lettere å skrive kode som er mer oversiktlig og er lett å lese. Dette fører igjen til at det er lettere å konsentrere seg om de problemene du faktisk skal gjøre, og å finne bugs når du leter etter dem.

 

Du er sikkert fortsatt uenig i en del jeg skriver, men jeg er gått lei denne diskusjonen og kommer ikke til å svare videre.

Endret av Skinney
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...