Cookies op Tweakers

Tweakers maakt gebruik van cookies, onder andere om de website te analyseren, het gebruiksgemak te vergroten en advertenties te tonen. Door gebruik te maken van deze website, of door op 'Ga verder' te klikken, geef je toestemming voor het gebruik van cookies. Wil je meer informatie over cookies en hoe ze worden gebruikt, bekijk dan ons cookiebeleid.

Meer informatie

Door , , 81 reacties

De C++-commissie van de ISO heeft het groene licht gegeven voor de final draft van de C++ 2011-norm. Naar verwachting wordt de specificatie van de vernieuwde programmeertaal in de komende zomer officieel gepubliceerd.

Het besluit om het ontwerp van de tot voor kort als C++ 0x bekende norm goed te keuren, viel vrijdag tijdens een vergadering van de ISO C++-commissie in Madrid. Nu de final draft international standard tot stand is gekomen, kan deze worden doorgeschoven naar de ITTF. Dit ISO-orgaan zal vermoedelijk in de komende zomer de C++ 2011-norm officieel vrijgeven en publiceren.

De huidige ISO C++-norm dateert uit 2003. Aan de opvolger C++ 0x is inmiddels acht jaar gesleuteld. De wijzigingen in de specificatie van de programmeertaal moeten C++ niet alleen eenvoudiger maken, maar ook efficiënter voor het programmeren van het opbouwen van code-bibliotheken. C++ 2011 biedt verder ondere andere betere multithreading-ondersteuning, meer mogelijkheden voor generiek programmeren en algemene prestatieverbeteringen. De GCC- en Visual C++-compilers zijn zo goed als klaar voor C++ 2011.

Tweakers .oisyn en Ruud v A, beiden lid van het C++-expertpanel van Tweakers.net, zijn enthousiast over de nieuwe norm. "De vijf belangrijkste features zijn wat mij betreft lambda's, variadic templates, r-value references, static type inference en multithreading", aldus .oisyn. "Eigenlijk is het schandalig dat C++ tot op heden nog geen support had voor multithreading. Uiteraard implementeerden gangbare compilers wel een goed gedefinieerd geheugenmodel en features om te multithreaden, maar het was gewoon niet gestandaardiseerd. Met C++-2011 is dat wel het geval."

Volgens .oisyn biedt de norm library-features om multicore programming makkelijker te maken en zijn de regels rond geheugen-access duidelijk in de norm opgenomen. "Zo mag een compiler bijvoorbeeld een onafhankelijke write van een variabele niet schedulen vóór een write naar een andere volatile variabele, ook al staat die eerste write chronologisch gezien in de code ná de volatile write."

Volgens Tweaker Ruud v A kan er dankzij C++ 2011 vooral mooiere code worden geschreven en worden er wat kleine ergenissen weggenomen. Ook hij noemt de lambda-functies. "Die gebruik ik zelf al vrij veel nu. Hetzelfde resultaat was al mogelijk met de vorige versie van de C++-norm, maar via een omweg."

Ruud v A vindt ook de nieuwe, uitgebreide random-library, die werd overgenomen van Boost, handig. "Verder is de toevoeging van de auto- en decltype-keywords erg handig. Hierbij zoekt de compiler het type van een expressie zelf uit, wat veel typ- en denkwerk scheelt. Wat verder nog een mooie toevoeging is, is de move-constructor. Deze heeft vooral invloed op de snelheid van programma's, die zo efficiënter worden."

Moderatie-faq Wijzig weergave

Reacties (81)

kan iemand wat toelichting geven over wat die rvalue vernieuwing inhoudt? ben wel benieuwd :)
Een rvalue reference stelt je in staat om een move-operatie uit te voeren. Voorheen was het voor verplaatsen nodig eerst een nieuw object te maken, dan alles te kopiŽren, en vervolgens het oude object weg te doen. Nu kan het nieuwe object gebruik maken van het oude object, dat immers toch nog in het geheugen zit. Zo bespaar je het kopiŽren, waardoor dingen sneller gaan.

Ook bij het invoeren in bijvoorbeeld een vector, kun je nu dingen rechtstreeks in de vector zelf construŽren. Voorheen moest je een object buiten de vector construŽren, en werd die vervolgens naar de vector gekopiŽerd.
bedankt voor de uitleg :)
Toen Wilbert me vroeg voor comments over C++ had ik een heel uitgebreid verhaal getypt, maar dat paste natuurlijk nooit allemaal in een simpel artikel. Maar hier het stukje over r-value references:

Een r-value is een resultaat van een expressie dat niet direct gekoppeld is aan een variabele of geheugenadres. Denk hierbij aan temporaries en literals. De naam komt van het feit dat r-values typisch die dingen zijn die aan de rechterkant van een assignmentexpressie staan, zoals in "foo = 4 / 2". Foo is hier een toekenbare variabele (en dus een l-value), en 4 / 2 is een r-value - het levert een int op, maar niet een object dat je aan kunt passen. Daarom mag je een expressie als 4/2 (en elke subexpressie die een tijdelijk resultaat oplevert) niet koppelen aan een non-const referentie - alleen maar aan const referenties. Dit om je te beschermen tegen aanpassingen aan een object dat daarna toch meteen opgeruimd wordt.

Met r-value reference kun je de compiler duidelijk maken dat je een referentie wilt hebben naar een object dat na gebruik opgeruimd mag worden. De reden hiervoor is tweeledig: het geeft move semantics, en perfect forwarding.

Met move semantics zijn optimalisaties mogelijk. Stel je kent de inhoud van een vector toe aan een andere vector. Wat er intern dan typisch gebeurt is dat er ruimte wordt gereserveerd met genoeg ruimte voor alle elementen uit de andere vector, die vervolgens worden gekopieerd. Afhankelijk van het aantal elementen en de kosten om een kopie te maken per element, kan dit een vrij dure operatie zijn. Als de toe te kennen vector daarna direct opgeruimd wordt, dan is de hele kopie overbodig geweest - de nieuwe vector had net zo goed de buffers van de op te ruimen vector kunnen overnemen, waardoor er niets gealloceerd en gekopiŽerd hoeft te worden. Met move semantics wordt precies dit mogelijk - bijvoorbeeld het resultaat van een functienaanroep kan op zo'n manier efficient worden toegekend aan een variabele zonder allerlei nutteloze dure kopieŽn. Ook is het nu mogelijk om zogenaamde move constructors te definieren voor objecten die bijvoorbeeld gebruik maken van een unieke niet kopiŽerbare resource (zoals een socket voor een netwerkverbiding) - het wordt dus mogelijk met move constructors om dergelijke ownership over te dragen aan een ander object van hetzelfde type.

Perfect forwarding was altijd een issue met template functies die hun parameters forwarden naar een andere functie, zonder dat ze kennis hadden over die andere functie. Een veelgebruikt voorbeeld zijn altijd factory methods die bijvoorbeeld een willekeurig object kunnen constructen. Omdat ze geen weet hebben van hoe de aan te roepen functie zijn parameters verwacht, moet je per parameter een overload maken zodat je de parameter by reference en by const reference door kan geven. Maar dit moet per parameter - voor functies met 4 parameters zit je dus aan 2^4 = 16 verschillende overloads. Met perfect forwarding blijft de typeinformatie van de parameter zoals meegegeven door de caller behouden, en is het net alsof de aan te roepen functie direct door de caller wordt aangeroepen. Dit klinkt waarschijnlijk onduidelijk, dus een voorbeeld:

template<class T, class P> T * New(const P & p)
{
return new T(p);
}

std::string str = "Hi there";
SomeObject * o = New<SomeObject>(str);

In dit voorbeeld wordt de functieparameter van New() by const reference doorgegeven. De constructor van SomeObject zal dus ook een const reference naar 'str' krijgen. Maar wellicht wilde de constructor wel juist een non-const referentie naar de string zodat hij 'm aan kan passen. Dan kun je New wel definieren als New(P & p), maar dat impliceert weer dat je 'm geen temporary of literal mag geven, want die kun je niet binden aan non-const references. En dus heb je twee versies van New nodig. Enter r-value references en forwarding:

template<class T, class P> T * New(P && p)
{
return new T(std::forward<P>(p));
}

de template argument deduction regels voor r-value references specificeren dat het type van de aanroep gerespecteerd moet worden. 'str' is een variabele, dus P zal worden gededuceerd als een non-const reference naar std::string.
De C++-commissie van de ISO heeft het groene licht gegeven voor de final draft van de C++ 2011-norm.
Is C++ commissie van de ISO zeker wereldwijd?
Tweakers .oisyn en Ruud v A, beiden lid van het C++-expertpanel van Tweakers.net, zijn enthousiast over de nieuwe norm.
Eerst dacht ik dat de tweakers .oisyn en Ruud v A ook adviezen aan C++ commissie van de ISO gaven tot ik op C++ expertpanel had geklikt... :')
De ISO C++ commissie (WG21) is formeel een vergadering van de nationale commissies. Vanuit Nederland is dit NEN/NNI (Nederlands Normalisatie Instituut). Aangezien die momenteel geen C++ expert hebben zouden .oisyn en Ruud v A zonder probleem lid kunnen worden en de ISO C++ commissie van advies voorzien. Heel moeilijk is het niet, het is voornamelijk een kwestie van geld: je wordt verondersteld op de meetings te verschijnen. Aan de andere kant is dat natuurlijk zonde als je geen daadwerkelijke bijdrage kunt leveren.
Staat deze versie van C++ los van de .NET ta(a)l(en) in Visual Studio?
Met andere woorden, moet Microsoft voor Visual Studio 2011 veel gaan sleutelen aan de compiler e.d. of is deze gewoon generiek te implementeren?
C++ produceert unmanaged code terwijl .NET een runtime omgeving biedt voor managed code. Beiden staan dus inderdaad los van elkaar.

Visual Studio is een Integrated Development Environment: zeg maar een ge-avanceerde "Notepad" voor programmeurs. Visual Studio is zelf geen compiler: het kan compilers wel aanroepen. Visual C++ is een van de compilers (van Microsoft) die vanuit Visual Studio aangeroepen kunnen worden.

Dat gezegd zijnde, vermoed ik wel dat Visual Studio aangepast zal worden voor autocomplete en betere ondersteuning van nieuwe features in de compiler/taal.
C++ kan best managed code produceren; dat is een implementatiekwestie. De standaard zegt helemaal niets over de stappen van compilatie, zolang het uiteindelijke programma maar doet wat het moet doen.
De standaard zegt helemaal niets over de stappen van compilatie
Nou (en wat nu volgt is ter lering en vermaak, niet ter nitpicking), daarin zijn zowel de C- als C++-standaarden nogal ongebruikelijk in de zin dat ze daar wťl dingen over zeggen, en nog best specifieke ook. Die hebben echter betrekking op hoe de compiler zich dient te gedragen wat betreft meerdere source files en hoe de linker het aan elkaar hoort te lijmen, en niet op welke object code er gegenereerd moet worden.

Voor beide talen geldt inderdaad wel het "as-if" principe, dat zegt elke implementatie die zich gedraagt alsof het letterlijk zo gedaan zou worden als de standaard beschrijft toegestaan is (ook al gebeurt er onder water eigenlijk iets heel anders). Noodzakelijk omdat de standaarden zeer operationeel geschreven zijn, in de vorm "doe dit en dan dat". Het gaat om het effect, niet de handelingen zelf.

Een C++-compiler mag dus prima managed code in een assembly produceren, en sterker nog, die van Microsoft doet dat ook gewoon. C++/CLI compileert naar IL, de machinecode van .NET. Er zitten ook nog extra constructies bij voor managed code, maar "gewone" C++ kun je er ook gewoon mee compileren (al heeft dat weinig meerwaarde als je de CLI-features niet gebruikt).
Visual Studio is zelf geen compiler: het kan compilers wel aanroepen. Visual C++ is een van de compilers (van Microsoft) die vanuit Visual Studio aangeroepen kunnen worden.
De releases van de compilers lopen echter wel gelijk op met de releases van de IDE, dus wat dat betreft is er wel een vrij strakke koppeling tussen de VC++ compiler en Visual Studio
Geen idee, maar het lijkt mij logisch dat elke compiler (gnu gcc, embarcadero, vs, etc. etc.) de features moet meekrijgen in een nieuwe versie.
De meeste compilers hebben bijna alle features al geimplementeerd, omdat voorgaande drafts al een tijdje beschikbaar zijn.
Hier is een overzicht te vinden van deze features voor GCC. In de latere versies werken veel features al perfect.
In Visual Studio 2010 is al een deel van de c++ 0x draft opgenomen. Een update van de compiler is nodig om de volledige standaard te implementeren.
Over c++ .NET, dat is een andere taal dan c++. Het bevat .NET specifieke extenties, ook die compiler stukken zullen uitgebreid moeten worden om c++ 0x code te kunnen ondersteunen.
C++ staat in principe los van .NET ( Behalve dat er ook C++/CLI is die het mogelijk maakt om C++ met .NET te combineren ), maar de compilers ervoor worden wel allemaal met Visual Studio meegeleverd (afhankelijk van welke versie je hebt natuurlijk), en dus lopen ze wel samen op. Dus de kans is groot dat alle features die nu nog niet geÔmplementeerd zijn pas bij de volgende release van VS.NET uitgebracht worden. Het is natuurlijk ook mogelijk dat MS het met een service pack mee laat komen, maar volgens mij hebben ze dat in het verleden in ieder geval niet gedaan.

[Reactie gewijzigd door Woy op 28 maart 2011 10:00]

Ik maak in mijn eigen projecten al een tijdje gebruik van C++0x features. Ben vooral blij met initializer lists waarmee type safe parameter lijsten mooier te implementeren zijn. Ook de variadic template parameter lists heb ik al een paar mooie dingen mee uitgehaald. Handigheidjes zoals het auto keyword (niet meer nodig om het type van een iterator in een for loop te definieren) zijn mooi meegenomen. De multithreading en random-libraries zijn ook toevoegingen die ik vaak zal gaan gebruiken.

Ik ben erg blij met de nieuwe standaard, laat het maar snel gemeengoed worden.
Ook aan de RUG wordt de nieuwe standaard al onderwezen. Dankzij variadic templates is het nu eindelijk mogelijk om 'echte' tuples te gebruiken. Ook de rvalue-references zijn een mooie toevoeging. Dmv perfect forwarding kan code nu stukken efficiŽnter worden.

Dingen als de multithreading en random library waren overigens al langer beschikbaar in de boost libraries. Dus ook voor gebruikers van de oude standaard waren deze technieken al te gebruiken.
Je bedoelt de C++ college's van Frank Brokken? Die heb ik zelf ook gevolgd en gebruik nog altijd de bijbehorende C++ Annotations ( http://www.icce.rug.nl/documents/cplusplus/ ) met veel informatie ook over de nieuwe standaard. Mocht je toevallig aan de RuG studeren en C++ willen leren dan zijn deze college's een absolute aanrader.
A.s. donderdag het laatste college. Dan meteen maar even een afspraak maken om de 15 punten binnen te hengelen :) .

Zijn C++ annotations zijn inderdaad behoorlijk uitgebreid en bevatten ook veel voorbeelden. Wel denk ik dat, als je zijn colleges niet gevolgd hebt, het boek een relatief hoge instapdrempel heeft. De opgaven bij het college waren dan weer wel dik in orde. Deze staan alleen niet in het boek, maar achter een login voor de deelnemers van het vak.

Mocht je een studie doen aan de faculteit wis- en natuurkunde in Groningen kan Brokkens colleges zeker aanraden.

YAY! voor anonymous functions btw. Geen gekloot met bind2nd of brokkens eigen fnwrap meer.
Iedereen gebruikt C0x al lang en de compilers hebben alles al 3 keer geÔmplementeerd. M.a.w. de echte wereld loopt voor op de de standaard. I.p.v. nieuwe mogelijkheden te scheppen vertraagd het de vernieuwing door nodige nieuwe features af te wijzen.

Geen ondersteuning voor concepts en te weinig verbeteringen voor templates maken dat C0x (c++ 2011) teleurstelt. Niet dat ik niet blij ben met de verbeteringen maar "too little too late" (hehe dat heb ik altijd al eens willen zeggen) . De standaard dat er al jaren geleden moeten zijn en de echte vernieuwingen zitten er nog niet eens in.

[Reactie gewijzigd door Punkie op 28 maart 2011 12:22]

C0x? Bedoel je de N1256 draft? Inmiddels hebben ze het daar over C1x, en dat is echt geen relevante standaard. Microsoft is niet eens van plan om C99 te implementeren, en ook daarbuiten is er maar beperkte support voor C99.

Als je't over C++0x hebt (en on-topic bent), dan is de compiler support al redelijk, maar verre van compleet. Anderzijds mag je nu verwachten dat de resterende gebieden nu wel snel gefixt worden. Het is niet zo dat de compiler bouwers nog moeten beginnen.
C++ is een van de meest lelijke talen die er is. Het staat bol van de complexe constructies, waarbij de een nog mooier dan de andere zou moeten zijn. In plaats van bezig te zijn met het oplossen van je probleem ben je dan ook meestal bezig om je door het oerwoud van constructies te worstelen. Waarbij je jezelf altijd de vraag stelt: waarom kan ik dat ene probleem met 3 verschillende constructies oplossen waar 1 eigenlijk voldoende was geweest. (Dit is puur mijn mening, andere ontwikkelaars kunnen natuurlijk een andere mening hebben)
C++ is een van de meest lelijke talen die er is. Het staat bol van de complexe constructies, waarbij de een nog mooier dan de andere zou moeten zijn.
Dit komt puur omdat je veel dichter op het "ijzer" programmeert. Je maakt direct gebuikt van pointers en stacks.

Als je dat niet wil blijf dan bij VB, C# of java. Met als gevolg langzamere programma's.
Java, PHP, C#, Python zijn geÔnterpreteerde talen. Er zit een extra laag tussen die de commando's doorvoert naar de Hardware. C/C++, Fortran zijn gecompileerde talen die tegen specifieke architectuur, besturingssysteem en libraries zijn gecompileerd.

Daarom zijn geÔnterpreteerde talen langzamer in het initialiseren, maar hoeven deze niet langzamer te zijn in de uitvoer. Bij taken waar veel I/O plaatsvindt (low-level operaties) is in de regel een gecompileerde taal 'sneller'. In Java, PHP, C# bestaan ook pointers maar deze worden altijd nog geÔnterpreteerd (niet direct omgezet naar machine taal).

Wat betreft de standaard zijn dit enkel de regels voor het gedrag van de taal. De compiler moet vervolgens ervoor zorgen dat deze juist is geÔmplementeerd.

[Reactie gewijzigd door ThePinguin op 28 maart 2011 10:23]

Java, PHP, C#, Python zijn geÔnterpreteerde talen.
Java en C# zijn bytecode talen.
PHP en Python zijn geÔnterpreteerde talen.
Wat betreft de standaard zijn dit enkel de regels voor het gedrag van de taal. De compiler moet vervolgens ervoor zorgen dat deze juist is geÔmplementeerd.
Klopt. Zoals ik al zei.
Omdat C(++) veel dichter op het "ijzer" zit, na assembly het dichtste op het ijzer.

Daardoor is het meer complex dan bijvoorbeeld Fortran en Pascal.
Daarom zijn geÔnterpreteerde talen langzamer in het initialiseren, maar hoeven deze niet langzamer te zijn in de uitvoer.
Een goed geschreven C(++) code is altijd sneller dan byte-code.
Java en C# zijn bytecode talen.
PHP en Python zijn geÔnterpreteerde talen.
Wat een ontzettend nutteloze klassificering. Je kunt ťlke taal interpreteren, en je kunt ťlke taal naar bytecode compileren. Er bestaan bijvoorbeeld gewoon bytecode compilers voor PHP.

De reden dat C++ complex is heeft overigens vrij weinig met z'n "lowlevelness" te maken. Het is historisch zo gegroeid - compatibiliteit met C is nog altijd een belangrijk punt, en het richt zich er heel erg op dat je user defined types kunt maken die zich net zo gedragen als built in types. Veel C++ features zouden ook gewoon prima werken in C#. Toch hebben ze er in Java en C# voor gekozen om bijvoorbeeld dingen als const en volatile niet te implementeren op object-niveau, om de boel simpeler te houden.
Een goed geschreven C(++) code is altijd sneller dan byte-code.
Complete nonsens. Je kunt hoogstens stellen dat C++ wat meer lowlevel features biedt die je in de meeste bytecode VMs niet tegenkomt (zoals pointers, unbounded array access, SSE intrinsics, etc.), maar dat betekent niet dat die features onmogelijk zijn in bytecode. Sterker nog, C++ kun je ook compileren naar bytecode.

Het voordeel van bytecode tov statisch gecompileerde code is dat de JITer de optimalisaties kan aanpassen aan het systeem waar hij op runt en de manier waarop de code tijdens runtime aangeroepen blijkt te worden. Natuurlijk kost JITen zelf ook tijd, maar wel maar eenmalig. En als dat betekent dat de machinecode zich kan aanpassen aan de runtime omstandigheden, kan ondanks de tijd die de JITer inneemt toch meer winst geboekt worden.

[Reactie gewijzigd door .oisyn op 28 maart 2011 12:02]

Java en C# zijn bytecode talen.
PHP en Python zijn geÔnterpreteerde talen.

Wat een ontzettend nutteloze klassificering. Je kunt ťlke taal interpreteren, en je kunt ťlke taal naar bytecode compileren. Er bestaan bijvoorbeeld gewoon bytecode compilers voor PHP.
Ik weet ook dat het in principe mogelijk is. Er zijn inderdaad PHP en Python bytecode compilers. Maar van origine zijn het geÔnterpreteerde talen.

Voor zowel C# als Java bestaan geen machinecode compilers. Dat dit wel mogelijk zou zijn is wat anders.
Een goed geschreven C(++) code is altijd sneller dan byte-code.

Complete nonsens. Je kunt hoogstens stellen dat C++ wat meer lowlevel features biedt die je in de meeste bytecode VMs niet tegenkomt (zoals pointers, unbounded array access, SSE intrinsics, etc.), maar dat betekent niet dat die features onmogelijk zijn in bytecode. Sterker nog, C++ kun je ook compileren naar bytecode.
Zoals je aangeeft, de lowlevel features zitten niet in bytecode.
En als dat betekent dat de machinecode zich kan aanpassen aan de runtime omstandigheden, kan ondanks de tijd die de JITer inneemt toch meer winst geboekt worden.
Deze zelfde optimalisaties zijn al door de compiler doorgevoerd voor machine codes. Deze kunnen veel tijd kosten waardoor deze niet in die mate wenselijk zijn op een VM machine. Je wil niet dat het minuten duurt voordat het programma opstart.

[Reactie gewijzigd door worldcitizen op 28 maart 2011 13:37]

Voor zowel C# als Java bestaan geen machinecode compilers. Dat dit wel mogelijk zou zijn is wat anders.
http://www.excelsior-usa.com/
Zoals je aangeeft, de lowlevel features zitten niet in bytecode.
Dat geef ik helemaal niet aan, je begrijpt me verkeerd. Ik zei dat je het in de meeste VMs niet tegenkomt. Maar dat betekent niet dat het niet kan. LLVM heeft namelijk vrij low-level bytecode, en er zijn gewoon compilers voor allerlei talen (inclusief C++) naar een LLVM backend. Kijk bijvoorbeeld eens naar llvmgcc.
Deze zelfde optimalisaties zijn al door de compiler doorgevoerd voor machine codes
Geoptimaliseerd voor een vooraf gedefinieerd systeem aan de hand van statische analyse van de code. De echt goede optimalisaties kun je doen als je weet hoe vaak elk stuk code wordt aangeroepen, welke branches wel en niet worden genomen, etc. Runtime analyse dus. Goede compilers kunnen optimaliseren aan de hand van eerdere profiling runs, maar het blijven kunstmatige testopstellingen. De echt zinnige profiling data is dynamisch en hangt af van het gebruik van de applicatie door de gebruiker.

Dit nog even naast het feit dat nieuwe hardware ook nieuwe instructies kent. Een JIT compiler kan hier in feite meteen gebruik van maken, een native gecompileerde app moet opnieuw gecompileerd worden (en dus heeft de gebruiker sourcecode nodig).

[Reactie gewijzigd door .oisyn op 28 maart 2011 18:42]

Voor zowel C# als Java bestaan geen machinecode compilers. Dat dit wel mogelijk zou zijn is wat anders.
MS levert er anders zelf een mee met het .NET framework: NGen

Meestal is het alleen verstandiger om dat aan de JIT over te laten aangezien die specifieke runtime optimalisaties kan doen.
goed geschreven C(++) code is altijd sneller dan byte-code
als het al zo is - wat dan nog?
Ook al zou het C# eindresultaat trager zijn dan een C++ programma wat hetzelfde technisch ontwerp volgt, dan NOG boeit het de klant niet: Klant heeft iets waar hij mee lekker kan werken, wat voor hem acceptabele performance geeft (anders piepen ze wel), en door de programmeur in acceptabele tijd is opgeleverd.

Voor elk doel is een tool de beste tool voor dat doel: Je gaat geen windows forms app maken met assembly language. Je gaat geen device driver schrijven in php.
Belangrijker is nog wel, je zit altijd met de mutually exclusive limieten van kwaliteit (in dit geval, performance) / functionaliteit / development tijd.

Misschien is C++ wel de enige taal waarin je op alle drie gebieden zeer goede resultaten kunt halen, maar dan nog is het IMHO veel moeilijker om mooie (lees: onderhoudbare) code te schrijven in C++ dan in zeg C#.
In mijn organisatie kiezen we voor kwaliteit (in de vorm van onderhoudbaarheid). Misschien had de applicatie een seconde sneller gedraaid als het puur C++ was geweest - maar dan hadden we hoofdpijn gehad bij het onderhoud. nu vinden wij dat een eitje.

(maar misschien zijn wij wel gewoon ruk-C++ programmeurs. wie zal het zeggen)

[Reactie gewijzigd door increddibelly op 28 maart 2011 11:08]

Voor sommige klanten is snelheid = lekker werken.
In de controle en Meet & regel wereld telt soms elke 100ste van een seconde.
ook voor drivers (hiervoor ook al vermeld) is snelheid van belang.
Wat ben je met een 6970 als de drivers trager werken dan die van een intel graka ?

In C++ kan je zonder veel moeite perfect leesbare en onderhoudbare code schrijven, zonder aan performantie in te boeten, maar dat ligt voor een groot stuk bij jou, en een deel bij de compiler (maar die moet dan weer door jezelf goed aangestuurd worden.)
goed geschreven C(++) code is altijd sneller dan byte-code

als het al zo is - wat dan nog?
Dit begint erg off-topic te gaan. Het originele topic was dat C++ complex is. De discussie was wat daar de reden van was.

Natuurlijk is het belangrijk dat je de voor jouw en voor het project de beste taal kiest.
Het is niet zo dat Perl/Ruby/Python/Java etc geen bestaansrecht hebben. In veel gevallen zijn deze talen de betere talen voor het project.

Zo heb je voor parse acties met perl, ruby etc veel sneller een resultaat.
En java is ideaal voor portable code.

Maar voor zaken die veel performance benodigd is C(++) vaak de beste keuze.

Zo zijn alle high performance game engines in C(++) en/of assembly geschreven

[Reactie gewijzigd door worldcitizen op 28 maart 2011 11:40]

Ik heb een redelijk ervaring in zowel C, C++ en assembly. C++ is bij uitstek het meest cryptisch. Ik betwijfel echter of C++ ook altijd het snelste van deze 3 is. Waar ik C++ een oerlelijke taal vind, daar vind ik C weer een hele mooie taal.
Een goed geschreven C(++) code is altijd sneller dan byte-code.
Daar zou ik maar geen vergif op innemen. Je kunt nog zo goed code schrijven, maar met een waardeloze compiler ben je nog steeds nergens. Het is bekend dat voor sommige hardware de kwaliteit van de beschikbare Java compilers bijvoorbeeld hoger is als van de beschikbare C/C++ compilers. Ik zou het woordje 'altijd' dan ook maar vervangen door 'meestal'
Welke exotische hardware heb jij het over? x86/64 niet, Intel maakt daar de meest performant compilers en die zijn voor C, C++ en FORTRAN. Op ARM heb je bijvoorbeeld Green Hills, die een stuk sneller is dan GCC.
Een goed geschreven C(++) code is altijd sneller dan byte-code.

Geen van beide is "sneller", zelfs de computationele complexiteit staat nog niet precies vast. Beide moeten namelijk nog vertaald worden naar echte machinetaal. De computationele complexiteit van de vertaalslag is bij byte-code vaak vrij klein vergeleken met C(++), je zou dus zelfs kunnen zeggen dat byte-code sneller is.

Zelfs een geÔnterpreteerde taal (haskell heeft voorbeelden) kan sneller zijn dan C(++) mits er precies de juiste operaties worden uitgevoerd.

Het is wel zo dat eenmaal gecompileerde talen vaak sneller zijn dan dingen die live naar een lager niveau geconverteerd moeten worden. Echter is dit verschil soms zo miniem* dat het niet meer uit maakt, zie bijvoorbeeld android telefoons die ondanks "restricted resources" gewoon bytecode applicaties hebben.

*gegeven dat de code efficient geschreven is en niet conceptuele fouten bevat (al dan niet door de taal logisch gemaakt).

Noot: ik heb soms bytecode met java verward misschien. Maar zeg nou zelf, welke andere bytecode taal heb jij ooit gebruikt?
Java, PHP, C#, Python zijn geÔnterpreteerde talen.
De meest gebruikte implementaties voor Java en C# maken echter gebruik van een JITter. Tijdens het runnen van je applicatie wordt de boel gecompileerd naar machineinstructies.
Bij taken als veel I/O (low-level operaties) is in de regel een gecompileerde taal 'sneller'.
Volgens mij bestaat I/O voornamelijk nog steeds uit calls naar het OS, dus ik zie niet in waarom een gecompileerde applicatie sneller zou zijn dan een geinterpreteerde applicatie.
Er zit een extra stap tussen wanneer je van een geÔnterpreteerde taal naar een het OS wilt gaan.

GeÔnterpreteerd: taal -> lib van programeertaal -> lib van het OS;
Gecompileerd: taal -> lib van het OS.
Nogal dubieuze opmerking dat het langzamere programma's zou opleveren... In de meeste gevallen zijn de compilers dusdanig intelligent, dat de afgeleverde code uiteindelijk exact hetzelfde is!

Geldt ook binnen talen... i++ of i=i+1 levert gewoon exact dezelfde code op. De compiler zorgt daar voor. Andere dingetje... Bij een for-loop met bijvoorbeeld 3 iteraties, wordt de code gewoon uitgeschreven, i.p.v. dat er een daadwerkelijke loop gemaakt wordt. Is namelijk sneller.

Zo is het dus maar de vraag of het daadwerkelijk gunstig is om zo dicht bij het ijzer te zitten. Verder zitten er ook grote nadelen aan al dat (meestal overbodige) pointer gebruik... het is namelijk dť toegang tot hacks via overflows. Iets dat in andere talen vaak gewoon afgevangen wordt.
Nogal dubieuze opmerking dat het langzamere programma's zou opleveren... In de meeste gevallen zijn de compilers dusdanig intelligent, dat de afgeleverde code uiteindelijk exact hetzelfde is!
Bytecode is processor onafhankelijk daarom kun je sowieso geen optimalisatie doen voor de betreffende processor wat bij C(++) code wel het geval is.
Daarbij moet de bytecode maar machine code omgezet worden wat ook tijd kost.
Geldt ook binnen talen... i++ of i=i+1 levert gewoon exact dezelfde code op. De compiler zorgt daar voor.
Nee. De een is bytecode de andere machine code die geoptimaliseerd is op de machine.
Jij haalt een aantal zaken compleet door elkaar.

Of een taal een normale compiler of een JIT compiler gebruikt heeft geen zier te maken met het wel of niet gebruiken van pointers.
(blijkbaar denk jij dat alleen Bytecode talen zonder pointers kunnen, maar dat is lariekoek)

Een goed voorbeeld is Turbo Pascal waar ik ooit mee begonnen ben met programmeren. Pointers waren vrijwel nooit nodig en de compiler kon ook checken op mogelijke buffer overflows. Daarmee ben je de bron van ellende van 90% van de security issues van vandaag de dag kwijt.

Terwijl de compiler gewoon identieke code leverde als hetzelfde programma in C of C++.

De stelling dat het gebruik van pointers en stacks serieus invloed heeft op de prestatie van een programma is gewoon niet waar.
(blijkbaar denk jij dat alleen Bytecode talen zonder pointers kunnen, maar dat is lariekoek)
Waar haal je vandaan dat ik dat denk.
Ik weet zeker dat ook C(++) zonder pointers kan programmeren.
Een goed voorbeeld is Turbo Pascal waar ik ooit mee begonnen ben met programmeren. Pointers waren vrijwel nooit nodig en de compiler kon ook checken op mogelijke buffer overflows. Daarmee ben je de bron van ellende van 90% van de security issues van vandaag de dag kwijt.

Terwijl de compiler gewoon identieke code leverde als hetzelfde programma in C of C++.
Je bedoeld code die het zelfde doet.
Want een Intel C compiler zal al andere machine code geven dan een gcc compiler (voor de zelfde processor architectuur).
De stelling dat het gebruik van pointers en stacks serieus invloed heeft op de prestatie van een programma is gewoon niet waar.
Dat je machine code i.p.v. bytecode gebruikt zorgt vooral voor de performance winst. Pointers kunnen op zich ook nog een performance winst opleveren.

[Reactie gewijzigd door worldcitizen op 28 maart 2011 11:52]

Waar haal je vandaan dat ik dat denk.
Omdat je in je reactie naar AHBdV over bytecode begint terwijl dat totaal niet aan de orde was.
Mijn conclusie is dan de enige logische, want een reden waarom jij ineens over bytecode begint is niet te bedenken.
Dat je machine code i.p.v. bytecode gebruikt zorgt vooral voor de performance winst.
Ah, dus je hebt je fout ingezien en komt nu terug op je eerdere uitspraak?
Daarin beweerde je namelijk nog dat het gebruiken van pointers en stacks de snelheidswinst gaf.
Pointers kunnen op zich ook nog een performance winst opleveren.
Je wilt het nog niet helemaal toegeven blijkbaar? Geef dan maar eens een voorbeeld om je statement te onderbouwen.

[Reactie gewijzigd door mjtdevries op 28 maart 2011 17:58]

Bytecode is processor onafhankelijk daarom kun je sowieso geen optimalisatie doen voor de betreffende processor wat bij C(++) code wel het geval is.
Optimalisaties zijn wel degelijk mogelijk. Ze geberen alleen op een ander moment.
Nee. De een is bytecode de andere machine code die geoptimaliseerd is op de machine.
Ze zijn volgens mij beide expressies er bestaat zover ik weet geen processor met de letterlijk machine code i++ of i=i+1. Zowel in Java bytecode als in de meeste machine code is het zoiets als INC [adressing mode]
Als performance je hoofdprioriteit is of als je per-sť low-level toegang nodig hebt tot de hardware, dan denk ik dat C++ daar de geschikte taal voor is. Denk maar aan het schrijven van device-drivers of een operating system...

Voor business-toepassingen denk ik dat managed code (en de bijhorende talen) beter geschikt zijn.
De meeste OS'en die ik ken worden in C gemaakt omdat dit voorspelbaarder is dan C++ (BSD, Linux, Windows). Drivers onder Linux iig zijn ook in C omdat er geen C++ runtime beschikbaar is.
C++ heeft geen runtime nodig, tenminste, niet anders dan C. Beiden hebben een runtime library, maar dat is voor spul als malloc cq. operator new. De Linux kernel bewijst dat je kunt booten zonder die libraries, dus daarvoor zou C++ geen probleem zijn.

Het grotere probleem is de ABI. C++ heeft overloading, wat betekent dat er twee functies kunnen zijn met 1 naam, maar verschillende argumenten. Het mechanisme om die uit elkaar te houden (name mangling) is niet overal gestandaardiseerd. Wel op Linux (Intel ABI) maar daar spelen de persoonlijke vooroordelen van Linux weer mee.
Ik denk dat je jouw reactie ook op een andere manier had kunnen verwoorden. Misschien was het dan niet jouw stijl geweest, of misschien was dan je boodschapt minder efficient, of juist efficienter overgekomen.

Uiteindelijk heb je weloverwogen hebt gekozen voor de meer beeldende, maar qua typewerk minder efficiŽnte constructie met een retorische vraag:
jezelf altijd de vraag stelt: waarom kan ik dat ene
.
Datzelfde punt had je zakelijker kunnen maken: "In plaats van slechts ťťn methode, zijn er verschillende wegen naar hetzelfde doel."

Er zijn maar weinig programmeertalen waar een doel op slechts ťťn manier te bereiken is, en C++ is daar geen uitzondering op.
Het is wel een van de meest flexibele talen maar ik snap je punt. Code geschreven in Java of PHP is vaak veel leesbaarder dan C++ code. Een van de grootste kritiekpunten was ook dat de C++ syntax te complex was geworden. Misschien is dat ook verbeterd in de nieuwe standaard?
Ja. Waar je vroeger "std::map<std::string, std::wstring>::const_iterator i = mymap.begin()" schreef, kun je nu "auto i = mymap.begin()" schrijven. Net zo typesafe, maar de compiler zoekt zelf uit wat het type van i is.
Het is natuurlijk goed dat ze C++ blijven ontwikkelen. Voorstanders zullen altijd de snelheid aanhalen. Terecht! Maar net als destijds met assembler, het gebruik zal marginaliseren in de loop de jaren, met uitzondering van een paar specifieke gebieden. De belangrijkste reden is dat snelheid steeds minder een issue wordt voor day-to-day programming. Belangrijker is dat je snel resultaat bereikt en je code kunt laten draaien. Nieuwere talen als Python maken die orde snelheidsverlies meer dan goed door een orde kortere ontwikkeltijd.

Dat C++ uit alle macht bij wil blijven op gebied van moderne programmertaalconcepten, leidt er inderaad toe dat de taal erg complex wordt. Maar niet alleen dat. De mensen die zich het nieuwe C++ eigen maken, zullen steeds grotere moeite hebben om hun code leesbaar te houden voor de nieuwere generaties programmeurs.

Tot slot toch nog een beetje typisch Tweakers.net irrelevante persoonlijke ervaring toegevoegd. Ik ben een half jaar geleden geswitcht van C/C++ naar Python, en zal in de toekomst alleen voor het hoogstnodige nog naar C/C++ grijpen. Ik heb in een half jaar meer in Python gedaan gekregen, en in prachtige elegante code, dan ik ooit voorelkaar gekregen zou hebben in jaren C++.
Het grootste voordeel van Python boven C++ is de aanzienlijke bak met standaard libraries die veelgebruikte methoden eenvoudig te gebruiken maken.

Ik ben nu zelf alweer een paar maanden bezig met Python, maar ik zit mezelf nog steeds regelmatig te ergeren aan de taal. C++ is voor mij stukken inzichtelijker en duidelijker dan Python. Niet in de laatste plaats dankzij het gebrek van accolades in Python om blokken code van elkaar te scheiden. Maar ook dankzij diverse constructies die gecompliceerde zijn dan nodig.

Bijvoorbeeld namespaces. In C++ zeer elegant geimplementeerd, goed bruikbaar en het zit je nooit in de weg. In Python zit je altijd met de modules te kutten met ingewikkelde prefixes; met als alternatief zelf aliassen definiŽren voor de klassen die je wilt gebruiken.

Het is dat ik momenteel vastzit aan Python voor mijn huidige project; als ik de kans had zou ik direct teruggaan naar C++. Ik ben dus ook erg blij met deze nieuwe norm van C++ en kan de doorontwikkeling alleen maar toejuichen.
Ik ben nu zelf alweer een paar maanden bezig met Python, maar ik zit mezelf nog steeds regelmatig te ergeren aan de taal. C++ is voor mij stukken inzichtelijker en duidelijker dan Python. Niet in de laatste plaats dankzij het gebrek van accolades in Python om blokken code van elkaar te scheiden. Maar ook dankzij diverse constructies die gecompliceerde zijn dan nodig.
Wat is het nut van accolades dan nog als je de scope al regelrecht uit het indent level kunt aflezen? Juist het weglaten van dergelijke overbodige elementen was voor mij een verademing toen ik begon met python :) Sowieso juist al die elegante syntax truckjes vind ik er zo mooi aan (tuples als return type, zonder rommel eromheen, list comprehensions, functies die je kunt behandelen als variabele, etc. etc.)

Dat het op andere punten nog beter uitgewerkt kan worden ben ik wel met je eens, al vind ik dat namespace deel nog wel meevallen. from ... import ... werkte anders dan ik in het begin dacht, maar als je dat soort dingen eenmaal weet valt er wel mee te werken. Al zou ik het zelf anders gedaan hebben als ik die taal ontworpen zou hebben (maar dat is makkelijk praten natuurlijk ;))

Ik werk momenteel afwisselend met .NET (C#) en python, en ben er nog niet over uit welke mijn favoriet is :) Maar ik ben iig blij dat ik niet meer met onnodig gecompliceerde talen hoef te werken.

Maar blijkbaar zijn de meningen nogal verdeeld, dus toch mooi dat talen als C++ ook nog doorontwikkeld worden :)
Het weglaten van accolades maakt iets wat in praktisch alle talen irrelevant is, whitespace, opeens wel relevant. Als je per ongeluk (bv omdat je op een andere pc werkt), een tab teken in plaats van 4 spaties oid gebruikt, dan is het indentation level niet meer gelijk en verslikt Python zich erin, of doet dingen die je niet verwacht. Hetzelfde geldt waarschijnlijk ook (al heb ik dit niet getest) voor newline characters die op Windows \r\n moeten zijn en op Unix slechts \n. Als je dit mixt boeit het voor de compilers van andere talen helemaal niets, alle whitespace wordt geskipt. In Python kan dat dan weer onverwachte resultaten geven.

Het weglaten van de puntkomma aan het einde van elk statement doet wederom hetzelfde; ik moet trucjes met line continuation characters doen om mijn statement over meerdere regels te splitsen om het leesbaar te houden.

De mogelijkheid om strings te enclosen in dubbele of enkele aanhalingstekens maakt het minder overzichtelijk en resulteert in code die door meerdere personen geschreven wordt in gebrek aan consistentie. In C++ geeft dit duidelijk het verschil tussen characters en strings aan.

En waar zijn essentiele operators zoals ++ en -- in Python (zowel prefix als postfix)?

Waarom is de syntax van de ternary operator in Python zo ondoorzichtig en tegenintuitief?

Waarom moet in een taal, die claimt leesbaarheid van de code voorop te hebben staan, elseif of else if, vervangen worden door elif?

Waarom moet er een dubbele punt voor een block staan als de indentation al genoeg is? Dan hadden ze net zo goed accolades kunnen gebruiken, dan was het einde tenminste ook zichtbaar.

Waarom is na 10 jaar van invoering, unicode nog steeds niet het standaard string type maar moet je er nog steeds een u voorzetten om je upper en lower functies goed te laten werken? Granted, dit is in C++ ook niet zo, maar dit zou juist een van de sterke punten van een nieuwe high-level programmeertaal moeten zijn.

Ook is de invloed die je hebt op wanneer variabelen en object gekopiŽerd worden veel te beperkt in Python, tov C++ waarin je door middel van pointers dan wel references daar volledige controle over hebt en je dus nooit voor verassingen komt te staan. En dan is bijvoorbeeld al een functie copy om dictionaries in Python te kopieren, maakt die weer alleen een kopie van de dictionary zelf, maar de values blijven naar dezelfde dingen wijzigen zodat de kopie nog steeds niet onafhankelijk is van het origineel. Nee, dan moet je er weer een extra package bijhalen om een deepcopy te maken.

Zo kan ik nog wel even doorgaan, maar mijn punt is wel duidelijk denk ik. Dingen die C++ juist zo onzettend handig maken missen gewoon van Python. Over C# kan ik weinig zeggen, hier heb ik me nog nooit aan gewaagd.

Ik heb op zich niets tegen scripttalen of andere high-level talen, maar je hoort regelmatig dat ze de heilige graal van het programmeren zijn en daar ben ik het niet mee eens; het is heel erg een kwestie van smaak en ook van toepassingsgebied.

Overigens kun je in C++ ook functies behandelen als variabele (zij het van type pointer). C++ doet echter wel garanties over de argumenten die deze variabele moet accepteren, terwijl Python dat niet doet. Tuples als return type zijn wel handig, maar in principe kan je daar in C++ net zo goed een vector oid voor gebruiken.

[Reactie gewijzigd door MadEgg op 28 maart 2011 11:56]

Het weglaten van accolades maakt iets wat in praktisch alle talen irrelevant is, whitespace, opeens wel relevant. Als je per ongeluk (bv omdat je op een andere pc werkt), een tab teken in plaats van 4 spaties oid gebruikt, dan is het indentation level niet meer gelijk en verslikt Python zich erin,
...en als je per ongeluk een accolade of een puntkomma vergeet in een taal als bijv. C krijg je ook een syntax error van de compiler.
of doet dingen die je niet verwacht.
Zoals?
Hetzelfde geldt waarschijnlijk ook (al heb ik dit niet getest) voor newline characters die op Windows \r\n moeten zijn en op Unix slechts \n. Als je dit mixt boeit het voor de compilers van andere talen helemaal niets, alle whitespace wordt geskipt. In Python kan dat dan weer onverwachte resultaten geven.
Python kan gewoon omgaan met een mix van LF en CR+LF.

(Ik gebruik hier expres niet \n, omdat de betekenis hiervan context-afhankelijk is. Zo is bijv. \n gedefinieerd als een newline in C, niet als linefeed.)
Het weglaten van de puntkomma aan het einde van elk statement doet wederom hetzelfde; ik moet trucjes met line continuation characters doen om mijn statement over meerdere regels te splitsen om het leesbaar te houden.
Dan zijn je regels te lang. Daarnaast zijn er bepaalde constructies in Python die geen eens line continuation characters nodig hebben (namelijk de constructies die (), [] en {} gebruiken).
De mogelijkheid om strings te enclosen in dubbele of enkele aanhalingstekens maakt het minder overzichtelijk en resulteert in code die door meerdere personen geschreven wordt in gebrek aan consistentie.
Die mogelijkheid stelt je in mijn ogen juist in staat om overzichtelijkere code te schrijven aangezien je escaping in bepaalde gevallen kunt ontwijken. In het volgende voorbeeld hoef ik in Python niets te escapen: 'deze Python string bevat "quotes" die niet geŽscapet hoeven te worden'.
In C++ geeft dit duidelijk het verschil tussen characters en strings aan.
En Python koos ervoor om geen chars te hebben. Guido vond dat je daarvoor strings ter lengte 1 kon gebruiken.
En waar zijn essentiele operators zoals ++ en -- in Python (zowel prefix als postfix)?
Die zijn niet essentieel. Als je in Python iets wilt verhogen, dan gebruik je +=1.
Waarom is de syntax van de ternary operator in Python zo ondoorzichtig en tegenintuitief?
Wat is er niet intuitief aan het volgende? print x/y if y != 0 else 'Cannot divide'

(Lees het eens hardop voor)
Waarom moet in een taal, die claimt leesbaarheid van de code voorop te hebben staan, elseif of else if, vervangen worden door elif?
Je hebt dan zeker ook problemen met het kunnen lezen van #elif van de C preprocessor? :p
Waarom moet er een dubbele punt voor een block staan als de indentation al genoeg is?
Staat in de Python FAQ.
Dan hadden ze net zo goed accolades kunnen gebruiken, dan was het einde tenminste ook zichtbaar.
Je kan het einde toch zien als je een stuk code tegenkomt dat minder ver is ingesprongen?
Waarom is na 10 jaar van invoering, unicode nog steeds niet het standaard string type maar moet je er nog steeds een u voorzetten om je upper en lower functies goed te laten werken? Granted, dit is in C++ ook niet zo, maar dit zou juist een van de sterke punten van een nieuwe high-level programmeertaal moeten zijn.
Python 3
Ook is de invloed die je hebt op wanneer variabelen en object gekopiŽerd worden veel te beperkt in Python, tov C++ waarin je door middel van pointers dan wel references daar volledige controle over hebt en je dus nooit voor verassingen komt te staan.
Het model van Python is echter heel simpel. Alle variabelen verwijzen naar een object en alleen verwijzingen worden gekopieerd (bij assignment en function calls).
En dan is bijvoorbeeld al een functie copy om dictionaries in Python te kopieren, maakt die weer alleen een kopie van de dictionary zelf, maar de values blijven naar dezelfde dingen wijzigen zodat de kopie nog steeds niet onafhankelijk is van het origineel. Nee, dan moet je er weer een extra package bijhalen om een deepcopy te maken.
Als je deepcopy nodig hebt, dan denk ik dat je opnieuw naar je probleem of je programmeerstyle moet kijken. Probeer bijv. een oplossing te vinden die functioneler van aard is.
Zo kan ik nog wel even doorgaan, maar mijn punt is wel duidelijk denk ik. Dingen die C++ juist zo onzettend handig maken missen gewoon van Python. Over C# kan ik weinig zeggen, hier heb ik me nog nooit aan gewaagd.
Dingen die Python zo ontzettend handig maken mis ik daarentegen in C++. ;)
Ik heb op zich niets tegen scripttalen of andere high-level talen, maar je hoort regelmatig dat ze de heilige graal van het programmeren zijn en daar ben ik het niet mee eens; het is heel erg een kwestie van smaak en ook van toepassingsgebied.
C++ heeft zeker een toepassingsgebied, maar dat gebied is lang niet meer zo groot als het vroeger was. De kracht van andere high level talen is juist dat je geen/minder rekening hoeft te houden met low level details waar je in bijv. C++ wel rekening mee moet houden.
Overigens kun je in C++ ook functies behandelen als variabele (zij het van type pointer).
Voor de introductie van lambda's waren functies in C++ nou niet echt bepaald first-class citizens. Hoe zou je de volgende Python functie implementeren in C++ zonder C++0x's lambda's?

compose = lambda f, g: lambda x: f(g(x))
C++ doet echter wel garanties over de argumenten die deze variabele moet accepteren, terwijl Python dat niet doet.
Python is dan ook wat dynamischer ingesteld dan C++. C++ is meer gericht op het geven van statische garanties, terwijl Python flexibeler probeert te zijn door deze niet te geven. Het flexibelere aspect is niet geheel zonder gevaar, maar er zijn ook onveilige dingen in C++ te vinden (die niet in Python voorkomen) waarbij de compiler je ook geen statische garantie kan geven.
Tuples als return type zijn wel handig, maar in principe kan je daar in C++ net zo goed een vector oid voor gebruiken.
Tuples zijn hier in Python vooral handig i.c.m. unpacking. Zonder unpacking zou het minder aangenaam zijn geweest.

[Reactie gewijzigd door RayNbow op 28 maart 2011 14:47]

...en als je per ongeluk een accolade of een puntkomma vergeet in een taal als bijv. C krijg je ook een syntax error van de compiler.
Correct. Maar het gebrek van de accolade kan je zelf zien. Het vervangen van tabs door spaties zie je niet en kan dus erg frustrerend werken.
Wat is er niet intuitief aan het volgende? print x/y if y != 0 else 'Cannot divide'
(Lees het eens hardop voor)
Intuitief zou het zijn als de juiste syntax was:

print x/y if y != 0 else print 'Cannot divide'

Zoals het moet in Python, is het krom Engels. Verder is het gebruiken van if als vorm van toekenning gewoon ontzettend raar voor iedereen die ooit heeft leren programmeren in een andere taal.

Op het moment dat je gewoon de ? operator gebruikt zal iemand die de constructie niet kent denken, goh, wat is dat, laat ik dat eens opzoeken. Bij het gebruik van if moet je tien keer opnieuw kijken wat er nu precies bedoeld wordt en opzoeken gaat je sowieso al niet lukken omdat de term 'if' in de context van programmeren dan nogal ambigu is.
Die zijn niet essentieel. Als je in Python iets wilt verhogen, dan gebruik je +=1.
En iets in deze trant dan?

size_t lines = 0;
while (file >> line)
cout << "Regel " << ++lines << ":" << line << endl;

In Python moet je dan voor het prefix ophogen van het regelnummer een apart statement gebruiken. Omslachtig.
Dan zijn je regels te lang. Daarnaast zijn er bepaalde constructies in Python die geen eens line continuation characters nodig hebben (namelijk de constructies die (), [] en {} gebruiken).
Het gebruik van een beetje descriptive variabele-namen dan al gauw 'te lange regels' op.
Je hebt dan zeker ook problemen met het kunnen lezen van #elif van de C preprocessor? :p
Die gebruik je toch aanzienlijk minder vaak dan de elseif if een gewone constructie. Als je veel preprocessor statements in je code gebruikt ben je wat mij betreft verkeerd aan het programmeren.
Je kan het einde toch zien als je een stuk code tegenkomt dat minder ver is ingesprongen?
Tenzij de regel ervoor ingesprongen is omdat het een vervolg is op de regel ervoor mbv een line continuation character. Daarvoor zijn de accolades dus handig.
Het model van Python is echter heel simpel. Alle variabelen verwijzen naar een object en alleen verwijzingen worden gekopieerd (bij assignment en function calls)
Het model is inderdaad heel simpel, dat is toch precies het probleem wat ik aankaart? In sommige situaties is het wel degelijk nuttig om kopieŽn van data te maken zonder dat expliciet met een statement te moeten doen. Neem bijvoorbeeld een implementatie van een minimax algoritme om de volgende set in een bordspel te bepalen. Om de bordsituaties te evalueren zul je een kopie van het bord moeten maken omdat je de uitgangssituatie niet kwijt wilt raken voordat er een beslissing genomen is.
Dingen die Python zo ontzettend handig maken mis ik daarentegen in C++. ;)
Die dingen zijn er ook zeker. Maar da's nog geen reden om dan C++ maar af te schrijven.
Voor de introductie van lambda's waren functies in C++ nou niet echt bepaald first-class citizens. Hoe zou je de volgende Python functie implementeren in C++ zonder C++0x's lambda's?
We hebben het hier toch juist over een nieuwe norm van C++ die wel lambda's introduceert? ;-)

[Reactie gewijzigd door MadEgg op 28 maart 2011 15:41]

Het vervangen van tabs door spaties zie je niet en kan dus erg frustrerend werken.
In elke fatsoenlijke editor / IDE krijg je een waarschuwing als je een mix gebruikt van tabs en spaces, en kan je met een simpele menu-functie of hotkey alles omzetten van tabs naar spaces of andersom.
En iets in deze trant dan?

size_t lines = 0;
while (file >> line)
cout << "Regel " << ++lines << ":" << line << endl;
(ervanuit gaande dat f een file object is:)

for i, line in enumerate(f.readlines()):
print 'Regel %d: %s' % (i + 1, line)

En ik vind het eigenlijk ook niet elegant om het uitlezen en het ophogen in 1 statement te combineren. Ik weet wel hoe het werkt, maar je moet toch altijd even nadenken. Heb dat ook heel vaak fout zien gaan bij beginnende programmeurs. En de ++ operator is al helemaal niet essentieel, aangezien je het nog altijd anders kan noteren of desnoods in meerdere statements. Ik merk daarnaast ook dat ik hem in Python zelden mis omdat for loops daar anders werken (op die plek gebruikte ik hem het meest in C/C++ e.d.).

[Reactie gewijzigd door Hiub op 28 maart 2011 16:41]

Mensen,

Het is niet heel erg nuttig om op zulk een kleine schaal naar de verschillen tussen C++ en Python te kijken, aangezien dit meer op voorkeur en gewenning aankomt dan dat het echt een wezenlijk verschil is. Dat bepaalde low-level dingen in Python niet direct(!) kunnen, zegt weinig omdat het gebruik van die constructs nooit een doel op zich is.

Wat wťl nuttig is, is kijken hoe lang het duurt voor je een werkend stuk code hebt, en hoeveel moeite het kost voor een ander om je code te begrijpen. En daar wint Python het gewoon met afstand van C++. Dat ligt aan de hoeveelheid syntaxfouten die gemaakt worden in C++, de omvang van de beschikbare bibliotheken in Python, de vrije coding style in C++, de omvang van de uiteindelijk code in verhouding tot de leesbaarheid ervan, noem maar op.

Als snelheid geen issue is, en het probleem niet in het bijzonder C++ of Python bevoordeelt, wil ik mijn had ervoor in het vuur steken dat een vaardige C++ programmeur het altijd aflegt tegen een vaardige Python-programmeur.
@HetMes:
Mits je het hier over project van enige omvang hebt en niet over een triviaal probleempje, ben ik overtuigd van het tegendeel. Een "hello world"-type applicatie heb je in Python inderdaad eerder voor elkaar.

Ik ben ervan overtuigd dat ik sneller een uitwerking in C++ voor elkaar heb dan een Python-guru in Python en dat de code ook nog minstens net zo goed leesbaar is (voor iemand die C++ kent natuurlijk). De resulterende binary zal ook nog eens sneller draaiden dan het Python-script.
Challenge accepted! Ben benieuwd...

Ik heb een Python generator functie waarmee je kunt itereren over alle permutaties van een string of lijst:

def permute(vector_a):
__if len(vector_a) == 1:
____yield vector_a
__else:
____for vector_b in permute(vector_a[1:]):
______for i in range(len(vector_b) + 1):
________yield vector_b[:i] + vector_a[0:1] + vector_b[i:]

En als dit nog onder 'triviaal' valt, waar gaat C++ dan de winst behalen?

[Reactie gewijzigd door HetMes op 28 maart 2011 17:24]

Dit noem je een project van enige omvang? Ik dus niet. Je hebt het hier over een concept wat in C++ niet bestaat dus je kunt wel op je vingers natellen dat de C++ uitwerking iets langer wordt.

Ik bedoel dus niet een simpele functie, ik bedoel een programma wat daadwerkelijk iets nuttigs doet.
Nee, dus waar gaat C++ winst behalen? Als het niet op kleine schaal is, waar dan wel? We hebben al vastgesteld dat Python meer standaard-bibliotheken heeft, dat Python een krachtigere taal is door het onbreken van bepaalde concepten in C++, we hebben het nog niet eens over metaclasses, function inspection, function decorators, tuple unpacking gehad.

Sterkte met je C++.
Challenge accepted! Ben benieuwd...
Challenge accepted. In C++ heb je gewoon de functie std::next_permutation(), die de volgende permutatie geeft gegeven een iterator range.

Overigens is deze hele discussie nutteloos. Beide talen hebben hun voordelen en nadelen. Er zijn gebieden waar C++ veel geschikter is dan Python, en andersom.

Tuple unpacking kan overigens gewoon in C++ 2011.

[Reactie gewijzigd door .oisyn op 29 maart 2011 01:11]

Bijvoorbeeld namespaces. In C++ zeer elegant geimplementeerd, goed bruikbaar en het zit je nooit in de weg.
Ik hoop dat dit een grapje is. C++ heeft zeker zijn goede kanten, maar namespaces zijn daar absoluut geen van. In feite zijn namespaces een vieze hack om problemen die door C++'s gebrek aan een ordelijk modulesysteem ontstaan zijn te verbloemen.

Juist in C++ moet je de hele tijd prefixen gebruiken, want in een header-file een "using namespace" opnemen is natuurlijk not done; daarmee importeer je voor iedereen die jouw header-file gebruikt ook de namespace, met alle mogelijke name-clashes van dien.
En dus typ je de hele tijd: std::string, std::vector<mijn_namespace::mijn_klasse*>, etc.
De using namespace moet je inderdaad niet in de publieke header zetten, maar in de interne header. Met als gevolg dat je alleen de volledige prefixen hoeft te gebruiken in de header, waar je als het goed is toch geen implementaties doet en in de gewone code kun je dan gewoon string, vector etc gebruiken.

@Antipater:

Forward declarations heb je niet vaak nodig; het is in vrijwel alle gevallen een optimalisatie om het compilen sneller te laten gaan omdat de compiler minder headers hoeft door te werken. Alleen in uitzonderlijke situaties is het een noodzaak, en anders heb je je code verkeerd geschreven. Bovendien hebben forward declarations vrij weinig invloed op je namespaces.

Verder zie ik niet in wat er onbegrijpelijk is aan de lookup regels, ik heb daar nog nooit problemen mee gehad.

[Reactie gewijzigd door MadEgg op 29 maart 2011 10:25]

Daar kan je dan nog de volstrekt onbegrijpelijke lookup regels aan toevoegen, de subtiele interacties tussen de preprocessor en templates en de noodzaak tot forward declarations. Die aspecten hebben allemaal consequenties voor hoe je met namespaces omgaat, omdat ze op niet-triviale wijze gevolgen hebben voor de namespace waarin je opereert.

Juist een beter module systeem was een van de features die voor deze iteratie zijn geschrapt, niet omdat het geen goed idee was, maar vanwege tijdsgebrek. Zonde.
Volstrekt onbegrijpelijke lookup regels? Tja, als je enerzijds OO hebt (en dus in base classes moet zoeken) en anderzinds echte operator overloading (dus niet de String+String hacks van andere talen), dan moet je inderdaad in meerdere richtingen zoeken.

Subtiele interacties tussen preprocessor en templates? Nou nee. Uberhaupt geen interacties. Zie "phases of translation". De laatste preprocessor instructie is compleet afgerond voordat de compiler uberhaupt naar templates kijkt.
C++ 2011 maakt de syntax wel mooier vind ik. Ook komen features zoals lambda, threads en andere mooie dingen uit boost over naar C++ 2011. Top allemaal!

Of C++ een mooie taal of niet is blijft natuurlijk een mening. Ik vind C++ niet lelijk en met frameworks zoals Qt ect. is C++ makkelijk te gebruiken voor simpele dingen :).
Balen dat ik net een boek heb gekregen om een beetje de basis van c++ te leren en dat ik nog geen tijd heb gehad om het daadwerkelijk te lezen. Het zal wel een beetje verouderd zijn eer ik er tijd voor heb. Maarja, het zat er ook al aan te komen.
De compiler geeft warnings als code deprecated is, het werkt nog prima meestal.
Dat is geen probleem. Veel van de veranderingen zitten niet in de basis dus daar zul je in eerste instantie weinig van merken. Ik heb zelf in 2007 C++ geleerd met behulp van een cursus uit begin jaren 90. Die was ook zwaar verouderd maar daar waar dingen niet werkten had ik dat met google er zo uit, en ik denk dat in jouw geval de verschillen een stuk kleiner zullen zijn.

Daarnaast zijn er ladingen aan programmeurs die op de nieuwe standaard over zullen gaan stappen de komende jaren dus je bent echt niet de enige. ;)
Hopen dat ik hiervoor alleen GCC hoef te updaten en niet ook nog mijn IDE (XCode), want dan weet ik vrij zeker dat het allemaal niet meer werkt.

Op dit item kan niet meer gereageerd worden.



Apple iOS 10 Google Pixel Apple iPhone 7 Sony PlayStation VR AMD Radeon RX 480 4GB Battlefield 1 Google Android Nougat Watch Dogs 2

© 1998 - 2016 de Persgroep Online Services B.V. Tweakers vormt samen met o.a. Autotrack en Carsom.nl de Persgroep Online Services B.V. Hosting door True