mboost-dp1

Jeremy Kratz

C++ får stor opdatering – første gang siden 2017

- Via Computerworld -

Det udbredte programmeringssprog C++ får snart en ny opdatering

Den sidste nye opdatering til C++ kommer til slutning af 2021. Det er første gang siden 2017, at sproget får nye funktioner.

Programmeringssproget blev udviklet af danske Bjarne Stroustrup i 1980’erne, og det har derfor nogle år på bagen.

C++ bliver brugt i blandt andet udviklingen af computerspil, og Microsoft brugte det til at bygge Windows.

De nye funktioner til C++ vil indholde det, der bliver kaldt ‘modules’ og coroutines.’





Gå til bund
Gravatar #1 - Claus Jørgensen
9. sep. 2020 12:41
Coroutines aka. Lazy/AsyncAwait/Yield

Modules aka. modules i alle andre programmeringssprog, i.e. hvor koden i en modul bliver kompileret separat, i stedet for at være en del af et massive header-dependency-tree.

Dvs. ting som stort de alle andre sprog har haft i 20 år.
Gravatar #2 - arne_v
9. sep. 2020 13:13
#1

Der var vist ikke mange sprog med coroutines i 2000.

:-)
Gravatar #3 - arne_v
9. sep. 2020 13:27
#0


Microsoft brugte det til at bygge Windows


Refererer CW korrekt:


Dengang var sproget helt afgørende for Microsofts arbejde med at bygge Windows, der blev lanceret senere det år


Men jeg mener ikke at det er korrekt.

Baseret på internet sladder så er:

Windows 3.x - assembler og C

Windows 9x - C med en lille smule assembler

Windows NT:

NT kerne - C med en lille smule assembler
Win32 sub system og Win32 API - C

Det er rigtigt at en masse Windows funktionalitet er C++ baseret: COM/ActiveX, MFC etc.. Men selvom disse er helt essentielle for meget Windows brug, så kan jeg ikke rigtigt se disse som "bygge Windows". Og det var først sidst i 90'erne at disse fik den store betydning.


Gravatar #4 - arne_v
9. sep. 2020 13:38
#0

Jeg skriver iøvrigt stadig C++ 98, så kald mig bare gammeldags.

:-)
Gravatar #5 - Claus Jørgensen
9. sep. 2020 14:50
arne_v (2) skrev:
#1

Der var vist ikke mange sprog med coroutines i 2000.

:-)
C# har da haft yield siden 2.0 (iterators), men også det var også i 2005, ikke 2000.


Gravatar #6 - Claus Jørgensen
9. sep. 2020 14:51
arne_v (4) skrev:
Jeg skriver iøvrigt stadig C++ 98, så kald mig bare gammeldags.

Hvorfor?

At bevist bruge en ældre version som tvinger dig til at skrive kode der er sværere at vedligeholde og har mindre sikkerhedsfunktionaliteter er ikke hvad jeg vil kalde smart.
Gravatar #7 - arne_v
9. sep. 2020 15:29
#6

Lidt vane og lidt hensyn til portabilitet (support for nye C++ version kan godt være lidt svingende - C++ 98 er et sikkert valg).
Gravatar #8 - arne_v
9. sep. 2020 15:35
#6

Og jeg ved ikke helt med vedligehold. Simpel kode er nem at vedligeholde. Smart kode er ikke nødvendigvis nem at vedliegholde.
Gravatar #9 - Claus Jørgensen
9. sep. 2020 15:56
#8

Det er kun rigtigt hvis du er den eneste der skal vedligeholde det. Hver gang du skriver og bruger kode som "erstatter" funktionalitet fundet i nye C++ udgaver, bliver det sværere og sværere at vedligeholde løsningen.

Boost er et rimelig godt eksempel på dette. Meget af funktionaliteten i boost er blevet erstattet af standard C++.

Men det er jo intet under at C++, ligesom Java, er ved at ende op som COBOL. Der er ingen under 40 der har lyst til at arbejde med en compiler fra det forrige årtusinde.
Gravatar #10 - Kirsebær
9. sep. 2020 18:41
#6 *bevidst
Gravatar #11 - Claus Jørgensen
10. sep. 2020 06:22
Gravatar #12 - DrHouseDK
10. sep. 2020 08:01
arne_v (3) skrev:
Det er rigtigt at en masse Windows funktionalitet er C++ baseret: COM/ActiveX, MFC etc.. Men selvom disse er helt essentielle for meget Windows brug, så kan jeg ikke rigtigt se disse som "bygge Windows". Og det var først sidst i 90'erne at disse fik den store betydning.

Er det ikke lige som at argumentere for at man ikke bruger vinduer for at bygge et hus?
Gravatar #13 - arne_v
10. sep. 2020 12:18
#12

Mere ligesom at argumentere for at pæne møbler ikke er en del af at bygge hus.

Det betyder meget for at kunne sælge, men har er ikke en del af det basale og kan sagtens tilføjes senere.
Gravatar #14 - arne_v
10. sep. 2020 12:27
Claus Jørgensen (9) skrev:

Det er kun rigtigt hvis du er den eneste der skal vedligeholde det. Hver gang du skriver og bruger kode som "erstatter" funktionalitet fundet i nye C++ udgaver, bliver det sværere og sværere at vedligeholde løsningen.


Hvis vi taler om at skrive hundreder / tusinder af linier kode i.s.f. at skrive 1 linie og bruge noget i standard bibliotek i nyere version, så er jeg enig.

Men jeg synes ofte at valget er mellem at skrive 10 linier der bruger seneste super feature eller at skrive 10 linier der gør tingene ligesom man altid har gjort.

Claus Jørgensen (9) skrev:

Boost er et rimelig godt eksempel på dette. Meget af funktionaliteten i boost er blevet erstattet af standard C++.


Der er stadig meget af Boost der ikke er i standard C++.

Claus Jørgensen (9) skrev:

Men det er jo intet under at C++, ligesom Java, er ved at ende op som COBOL. Der er ingen under 40 der har lyst til at arbejde med en compiler fra det forrige årtusinde.


Jeg skal ikke udtale mig om hvad folk har lyst til.

Men de fleste arbejder nok med sprog fra før år 2000.

C, C++, Java, Python, PHP etc..
Gravatar #15 - Claus Jørgensen
10. sep. 2020 12:31
#14

Sprog ja, version nej. At bruge C++98 er ligesom at bede en PHP udvikler om at bruge PHP 4. Der er der ingen seriøse PHP udviklere der gør.

Hvis en virksomhed kom og sagde at de lavede alt deres udvikling i C++98 ville jeg tænke "okay, så de har ikke opdateret deres teknologi siden forrige årtusinde, så må resten af virksomheden være utrolig gammeldags -- de bruger sikkert også waterfall"

Og jeg ville heller ikke arbejde for en virksomhed der bruger en 20 år gammel udgave af Java, det er helt sikkert.

Virksomheder der tænker på den måde tager ikke teknologi seriøst, og derfor vil jeg tvivle på at deres udviklere tager deres job seriøst -- fordi hvis de gjorde arbejde de jo nok hos en virksomhed med opdateret teknologi.
Gravatar #16 - arne_v
10. sep. 2020 12:41
#15

Så misforstod jeg dig.

Praktisk talt alle virksomheder vil bruge rimeligt nye versioner af compilere med support for nyere versioner af sproget for nye projekter.
Gravatar #17 - arne_v
10. sep. 2020 12:44
#16

Gamle projekter er noget andet.

Grundliggende har man valget:
A) beholde kode og beholde gammel compiler
B) beholde koden og opdatere compiler og tweake settings til det virker
C) opdatere kode og opdatere compiler

Hvis jeg skulle gætte på fordeling så: 30%, 65% og 5%. :-)
Gravatar #18 - Claus Jørgensen
10. sep. 2020 12:46
#16

Så du undgår bare at bruge nye features selvom det er supportet af din toolchain?

Det er da endnu mere underligt. Jeg ville typisk ikke godkende et pull-request der ikke udnytter nye funktionaliteter.

F.eks. ville jeg forvente C++ udviklere at bruge std::reduce over at skrive et for loop manuelt.
Gravatar #19 - arne_v
10. sep. 2020 14:16
Claus Jørgensen (18) skrev:

Så du undgår bare at bruge nye features selvom det er supportet af din toolchain?


Det afhænger af omstændighederne.

Claus Jørgensen (18) skrev:

F.eks. ville jeg forvente C++ udviklere at bruge std::reduce over at skrive et for loop manuelt.


Det er faktisk et godt eksempel til at illustrere problematikken.


int sum1(vector<int> v)
{
return reduce(v.cbegin(), v.cend(), 0, plus<>());
}


vs


int sum2(vector<int> v)
{
int sum = 0;
for(int i = 0; i < v.size(); i++) sum += v[i];
return sum;
}


Den første kode kræver at compileren understøtter C++ 17 og kræver at udvikleren kender reduce for at kunne forstå koden.

Den anden kode kræver at compileren understøtter C++ 98 og at udvikleren kender et sprog med C syntax (C, C++, Java, C#, PHP etc.) for at kunne forstå koden.

Hvis restenkoden er fuld af lignende konstruktioner, så kan koden ikke compiles med en gammel compiler og Java/C# udvikleren er tabt alligevel, så kan man lige så godt bruge reduce.

Men hvis resten af koden er gammeldags/simpel kode, så er for løkken faktisk bedre kode. Den compiler overalt og stort set alle udviklere forstår hvad koden gør.
Gravatar #20 - Claus Jørgensen
10. sep. 2020 14:28
#19

Men hvis compiler versionen ikke er et problem, så ville jeg forvente at du brugte reduce. Specielt til mere kompliceret expressions.

Og at udviklere ikke kan forstå lambda expressions er deres problem, det er ikke en undskyld for ikke at bruge dem. (C# havde samme diskussion for mange år siden)

C++ har aldrig været et sprog der har været sky fra at bruge obskurt kode, templates er måske det bedste eksempel i hele verden på kode det er stort set ulæseligt, og bruges i often overdreven forstand.

Så at C++ udviklere ikke skulle kunne forstå lambdas/closures finder jeg ret usandsynligt.
Gravatar #21 - arne_v
10. sep. 2020 15:01
#20

Brugerne af visse sprog kan godt lide indviklede konstruktioner. C++, Ada, Scala etc..

Men i den virkelige verden er simpelt godt.

For ca. 25 år siden så jeg en vittighed. Den viste hello world for forskellige niveauer af udviklere:

begynder: Basic
godt igang: Pascal
erfaren: C
meget erfaren: C++
ekspert: C++ GUI
guru: Basic

Gravatar #22 - arne_v
10. sep. 2020 15:07
#20 og #21

Et andet aspekt er standardiseringsprocessen.

En anden relevant vittighed: "An elephant is a mouse designed by a committee".

Nogen gange er det gyseligt hvad der kommer ud af de processer.

Et af de værste eksempler jeg kender er Java compiler API. Man har en String variabel med en klasse og man vil have et objekt af den klasse. Simpel problem stilling. Det kræver ca. 5 linier i .NET. Hvor kompliceret kan det gøres? Meget! Det beviste JCP ved at definere et API som kræver at man skriver et par hundrede linier kode.
Gravatar #23 - larsp
12. sep. 2020 09:49
Hvilke egenskaber skal man dyrke hvis man vil være en god programmør?

Mit svar er at være dum og doven.

Dum fordi jo mindre mental indsats det kræver at skrive og læse noget kode, jo bedre. Keep it simple stupid.

Doven fordi det bør gøre ondt at gentage sig selv og at lave overflødige konstruktioner.

Jeg kan bedst lide sum2 funktionen i #19 ud fra målet om at skrive transparent og letforståelig kode. På den anden side læser jeg at std::reduce kan åbne døren for parallelization optimizations. Det lyder egentlig ret cool. Selvom der er lidt for meget sort magi over det for min smag.
Gravatar #24 - Claus Jørgensen
12. sep. 2020 11:01
#23

Hvis man ser lamba funktioner som sort magi så er man en dårlig programmør, ikke en doven programmør.

Det er faktisk lidt underligt at se arne_v ikke være for absolut brug af map/reduce/fold siden han altid argumentere for at folk burde tage en kandidatgrad i datalogi. Jeg kan ikke forestille mig at en datalog ikke kender til map/reduce/fold/lambda/pattern-matching etc.

Og lambda expressions (som f.eks. reduce) kræver typisk meget mindre kode.

Med coroutines i C++ kan de sandsynligvis også bygge et effektivt builder pattern, ala. https://developer.mozilla.org/en-US/docs/Web/API/F...
Gravatar #25 - larsp
12. sep. 2020 11:12
#24 Det var nu parallelization optimizations som spontant sker ud fra en simpel oneliner jeg hentydede til som sort magi.

Til systemprogrammering foretrækker jeg kode der eksplicit fremstiller hvad den gør.
Gravatar #26 - Claus Jørgensen
12. sep. 2020 11:20
Her et et andet eksempel på hvor fold er nyttigt, vs. den "traditionelle" måde.


// C++17
#include <iostream>
#include <numeric>
#include <vector>

int main(int argc, const char * argv[]) {
std::vector<std::string> strings = { "Hello", "World", ",", "Oh", "Wait", "no", "the", "world", "is", "on", "fire" };

auto result0 = std::reduce(std::next(strings.begin()), strings.end(), strings[0], [](std::string a, std::string s) {
return a + " " + s;
});

// vs

auto result1 = std::accumulate(std::next(strings.begin()), strings.end(), strings[0], [](std::string a, std::string s) {
return a + " " + s;
});

// vs

std::string result2 = strings[0];
for (int i = 1; i < (int)strings.size(); i++) {
result2 += " ";
result2 += strings[i];
}

std::cout << "[" + result0 + "]" << std::endl;
std::cout << "[" + result1 + "]" << std::endl;
std::cout << "[" + result2 + "]" << std::endl;
return 0;
}


https://gist.github.com/clausjoergensen/b6855dcdbd... (newz.dk er dårlig til at vise kode)

Det vigtigste her er at et for loop har side-effekter, hvor er i et fold lambda er det ikke muligt.

Og nogle længere mere matematiske eksempler: https://stackoverflow.com/questions/47144083/why-h...
Gravatar #27 - Claus Jørgensen
12. sep. 2020 11:34
Og så kan man jo bruge det til at skrive smuk og sikker kode som


std::string join(std::vector<std::string> elements, std::string seperator) {
    if (elements.empty()) {
        return std::string("");
    }

    return std::reduce(std::next(elements.begin()), elements.end(), elements[0], [seperator](std::string a, std::string s) {
        return a + seperator + s;
    });
}


(heh, man kan lave indents på newz.dk hvis man bruger et andet unicode spaces end alm. space)
Gravatar #28 - arne_v
12. sep. 2020 12:11
Claus Jørgensen (24) skrev:

Det er faktisk lidt underligt at se arne_v ikke være for absolut brug af map/reduce/fold siden han altid argumentere for at folk burde tage en kandidatgrad i datalogi. Jeg kan ikke forestille mig at en datalog ikke kender til map/reduce/fold/lambda/pattern-matching etc.


Jeg mener absolut at udviklere bør kende reduce.

Men jeg mener ikke at udviklere bør antage at alle andre udviklere kender reduce.

Forskel.

Claus Jørgensen (24) skrev:

Og lambda expressions (som f.eks. reduce) kræver typisk meget mindre kode.


Der er masser af tilfælde hvor lambda funktioner giver mere læselige kode.

Og er fordelen stor nok, så giver det god mening at bruge dem.
Gravatar #29 - arne_v
12. sep. 2020 12:26
larsp (23) skrev:

Jeg kan bedst lide sum2 funktionen i #19 ud fra målet om at skrive transparent og letforståelig kode. På den anden side læser jeg at std::reduce kan åbne døren for parallelization optimizations. Det lyder egentlig ret cool. Selvom der er lidt for meget sort magi over det for min smag.


Har man brug for at paralellisere, så giver noget som reduce absolut mening.

Men så er man også udover det trivielle.
Gravatar #30 - arne_v
15. sep. 2020 15:14
#27

Jeg synes ikke at den kode er smuk.

Den er langt mere kompliceret end nødvendigt.

Med en for løkke:


string join(vector<string> elements, string seperator)
{
string res = "";
for(int i = 0; i < elements.size(); i++)
{
if(i > 0) res += seperator;
res += elements[i];
}
return res;
}
Gravatar #31 - Claus Jørgensen
15. sep. 2020 15:28
#30

Der er jeg så fuldstændig uenig. Men jeg arbejder også it sprog hvor vi bruger map/reduce/fold/lambdas til dagligt, så jeg er nok mere komfortable med dem end en C++/Java udvikler ville være.

Swift er faktisk gået så langt at for(var i=0;i<count;i++) {} løkker ikke længere er muligt. Det er fantastisk.
Gravatar #32 - arne_v
15. sep. 2020 16:57
#31

for(var i = 0; i < count; i++)

duer ikke, men så kan man:

for i in 0..<count


Gravatar #33 - CBM
16. sep. 2020 18:51
arne_v (30) skrev:
#27

Jeg synes ikke at den kode er smuk.

Den er langt mere kompliceret end nødvendigt.

Med en for løkke:


string join(vector<string> elements, string seperator)
{
string res = "";
for(int i = 0; i < elements.size(); i++)
{
if(i > 0) res += seperator;
res += elements[i];
}
return res;
}



prøv med en LARS løkke


string join(vector<string> skandaler, string pingvin)
{
string sko = "";
for(int lars = 0; lars < skandaler.size(); lars++)
{
if(lars > 0) sko += pingvin;
sko += skandaler[lars];
}
return sko;
}
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login