C++ och dess framtid att programmera minnessäkert - Hur går utvecklingen?

Permalänk
Medlem
Skrivet av klk:

Hur lyckas du? Vad jag än skriver så lyckas du tolka det på ett totalt annorlunda sätt. Påstår inte att jag är något språkgeni, långt ifrån men så otydligt var det väl inte?

I detta fallet så sa jag inte emot dig. Det är känsligt och jag har stött på personer som varit extremt känsliga. Jag hade en före detta kollega som bokade samtal med chefen efter min första review-kommentar som bad personen att dela på en git-commit. Personen uppfattade detta som mobbing och tog väldigt illa åt sig.

Min kommentar bör läsas som "Det är känsligt men det är ohälsosamt att identifiera sig så pass mycket med sin kod att det blir känsligt".

Permalänk
Medlem
Skrivet av orp:

I detta fallet så sa jag inte emot dig. Det är känsligt och jag har stött på personer som varit extremt känsliga. Jag hade en före detta kollega som bokade samtal med chefen efter min första review-kommentar som bad personen att dela på en git-commit. Personen uppfattade detta som mobbing och tog väldigt illa åt sig.

Min kommentar bör läsas som "Det är känsligt men det är ohälsosamt att identifiera sig så pass mycket med sin kod att det blir känsligt".

Ok, jag kanske misstolkade men jag reagerade på att man är känslomässigt knuten till koden.
Jag tycker visserligen inte det är dåligt om programmerare vårdar sin kod, att man tycker om kod och även annan kod men det bör vara på rätt sätt. Aldrig vara rädd att slänga kod exempelvis.

Min poäng handlade snarare om att man blottar sig, brister och annat för det tror jag nog alla utvecklare vet, att få sin kod granskad är darrigt

Permalänk
Medlem
Skrivet av Yoshman:

Håller med. Men ser inte varför något i Rust skulle förhindra det.

En ett exempel på något som snarare gör att man lättare tar sig "snabbt fram" med Rust jämfört med många andra språk är saker som att "arithmetic overflow" ger notis i _debug byggen_ i Rust (men inte i Release för att inte påverka prestanda).

Kan de vara så att utvecklare i rust inte använder debugger eller inte alls lika mycket och orsaken till det är att språket har dessa hinder i sig. Smäller det inte lika ofta är det kanske inte det verktyget man lär sig mer än när det blir nödvändigt?

Skrivet av Yoshman:

Det är "opt-in" att stänga av alla former av rail-guards.

Ja, är medveten om att det i rust som i så många andra program går att "stänga av saker". Det borde väl till och med att koda assembler i rust precis som det går att göra i C/C++ och andra språk med gissar jag.
Men för att stänga av saker i språk, frångå principerna. Där är min erfarenhet att det skall väldigt mycket till innan någon gör det. Knappt att jag har sett det.
För flera år sedan jobbade jag med en del C# utvecklare, samtliga mina förslag på att försöka lösa problem "smartare" med då runda hur man normalt kodar i C# ratades. Att göra "black box" lösningar var det tvärnit för.

Och för att förtydliga, presenterade jag en lösning för dem som hade halverat mängden kod, dessutom gjort koden flexibel. Låt säga att ett projekt bestod av 1 miljon rader, och man kunnat halvera den mängden.
Det gick inte.

Skrivet av Yoshman:

Har använt TDD i C#, Go, Rust, C++ och även C. Det fall som varit mest "coolt" är så här långt i C där vi jobbande i månader med ett projekt där vi hela tiden höll 100 % test-coverage.

För mig är det inte något possitivt att läsa. Enligt mig är det viktigt att utvecklare lär sig och framför allt lär sig vad som händer när de gör sönder koden. Helst innan koden går sönder hos kund.
När saker går sönder, det är då man lär sig som mest.
Programmerare som aldrig slitit med skitkod eller trasslat in sig, tveksamt om de ens kan kalla sig för programmerare.

Skrivet av Yoshman:

Här ser man också skillnad i de "nya" språken. Både Rust och framförallt Go har TDD integrerat i standard tool chain (Go har även mikrobenchmarks där, Rust kräver likt C++, C# m.fl. 3:e-parts bibliotek men där det finns "de-facto standarder").

Desto mer jag lär mig om rust, det går åt andra hållet. Har de byggt in sådant också... Vet att en del som kodat rust och byter till annat kritiserar rust för att det blir så mycket "skräp" och jag börjar förstå varför.
Samma fenomen finns i frontend och javascript. Förr gjordes en frontend med lite javascript och några html sidor. Idag är minsta lilla skitlösning flera megabyte med bibliotek och annat.

Skrivet av Yoshman:

Ge ett enda konkret exempel!

Men då tror flera att jag skryter. Och jag menar inte att det inte går att göra saker i andra språk, det går att göra det mesta i python med, bara man har en säng bredvid datorn så man kan ta sig en tupplur innan programmet jobbat färdigt.

Det senaste jag satt med, i början på veckan var en liten grej för att parsa stora filer.
Kommentar från koden

* \brief A flexible buffer class for managing linear data with look-ahead capabilities. * * The line class provides a buffer implementation that supports efficient reading, * writing, and processing of linear data. It maintains a main buffer of specified size * and capacity, along with a look-ahead buffer positioned after the main buffer. * * Key features include: * - Automatic buffer rotation to efficiently handle continuous data streams * - Capacity management to prevent buffer overflows * - Look-ahead buffer support for parsers or processors that need to peek ahead * - STL-compatible iterators for standard algorithm compatibility * - Automatic conversion to string_view for string operations

Den här typen av lösningar görs knappt i andra språk. Varför kan man undra men det handlar ju inte om att det inte går.

Skrivet av Yoshman:

Är helt med på att väldigt få tragglar med template-meta-programming eller ens gör egna containers eller liknande. Men det gäller oavsett om det är C++, Rust, C# eller vad det nu är.

Ja och många av de som faktiskt gör det läser koden i stl och tror de skall skriva templates precis som de skriver stl och det tror jag skrämt iväg en hel del.
Annars så är just templates något som blivit enklare och bättre med senare versioner av C++ och ser själv fram emot C++26 som ytterligare förenklar. Framförallt är det inte längre så svårt att göra koden så mycket mer flexibel.

Permalänk
Skrivet av klk:

Får jag säga samma sak då, för varför tror du automatiskt jag har fel? Finns gott om literatur kring det här men det är kanske inte den mest lästa då administration av kod brukar hamna långt ner i "rolighetslistan" för kodare.

Jag har uppfattat det som att du, när du ser en rad av funktionsanrop (a()->b()->c()->d()), reflexmässigt slår bakut och säger message chaining.

I många fall har du rätt i att resultatet av detta blir coupling, men det är inte så att en rad av anrop automatiskt innebär den skadliga coupling vi talar om här. Jag försökte påvisa att det inte är de kedjade anropen i sig som skapar coupling utan att det faktum att koden kommer bero på att de olika anropen returnerar ett resultat av en viss typ. Om a() returnerar något som inte har en b-metod kommer det inte kompilera. Om du bryter kedjan till enstaka anrop och stoppar resultaten i temporärer kommer du få precis samma beroenden. Dessa kommer ställa till det vid refactoring även utan att anropen är kedjade.

I pipeline-fallet är map, reduce, filter och andra funktioner metoder i container-klassen. De är designade för att man skall kunna göra just pipelining. Jag måste säga att

let evens: Vec<_> = vec![1, 2, 3, 4].into_iter().filter(|x| x % 2 == 0).collect();

är lite elegantare än

std::vector<int> nums = {1, 2, 3, 4}; std::vector<int> evens; std::copy_if(nums.begin(), nums.end(), std::back_inserter(evens), [](int x) { return x % 2 == 0; });

Kallar du detta coupling? Visst, det förutsätter att map och filter returnerar en container men det är ett designbeslut man har tagit för att kunna pipelining. Skulle det ställa till det om du vill ändra på map och filter, jajamänsan, men du kommer med största sannolikhet inte behöva göra refactoring på container-klasserna. Detta är kedjade anrop som inte ger coupling, alla beroenden är inom container-klassen.

Skrivet av klk:

När det gäller rust och konstruktör problemet är inte problemet med coupling lika stort sett till objektet som jobbas med. Så länge allt hanteras av ett enda objekt och man inte blandar så går det och släppa igenom i nödfall. Men det kräver då att utvecklaren håller den disciplinen och inte lägger in annan cool kod i argumenten.
Det är fortfarande ingen bra lösning på något vis men jag antar att i Rust finns det inte så mycket alternativ.

I builder-fallet ser jag inte som en begränsning att returnera self från "del-konstruktorerna". Ok, koden beror på att man gör det, men så gör man i Rust. Coupling, njäe. Förresten, är det inte analogt med att en constructor i C++ implicit returnerar objektet du just initierat. Tycker du det är en begränsning att du inte kan returnera en annan typ från en constructor?

Kör du inte själv med snarlika tekniker där du delegerar till common() att sköta delar av constructor-jobbet? I Rust behöver du inte göra allt i en funktion utan kan bryta upp det i mindre, naturliga bitar.

Permalänk
Skrivet av klk:

Kan de vara så att utvecklare i rust inte använder debugger eller inte alls lika mycket och orsaken till det är att språket har dessa hinder i sig. Smäller det inte lika ofta är det kanske inte det verktyget man lär sig mer än när det blir nödvändigt?

Jag använder ofta debugger i Rust på samma sätt som jag gör i C++ och C#. En skillnad är dock att man mer sällan behöver debugga Rust kod. Ofta är det till och med snabbare att slänga in en `#[derive(Debug)]` och snabbt få se hur datan ser ut. Den sortens introspection saknas i C++ (och i de allra flesta språk).

Skrivet av klk:

Desto mer jag lär mig om rust, det går åt andra hållet. Har de byggt in sådant också... Vet att en del som kodat rust och byter till annat kritiserar rust för att det blir så mycket "skräp" och jag börjar förstå varför.

Ena stunden klagar du på att Rust saknar features (överlagring, konstruktorer etc.) och nu klagar du på att unit testing är inbyggt? Det låter mest som att du klagar på Rust för att det inte heter C++. Tidigare i tråden har du också sagt att C++ är mer explicit än Rust. Det är faktiskt så att det omvända är sant. Rust är mer explicit. Men nu bara för att jag säger att Rust är mer explicit kommer du kontra med att explicit kod inte är bra kod eftersom att C++ inte är så. Det är ungefär så här jag tolkar hela ditt luddiga resonemang i den här tråden. Du är programmeringsvärldens version av en fotbollssupporter. "Mitt lag är bra och ditt lag är dåligt oavsett vad resultatet visar".

Skrivet av klk:

* \brief A flexible buffer class for managing linear data with look-ahead capabilities. * * The line class provides a buffer implementation that supports efficient reading, * writing, and processing of linear data. It maintains a main buffer of specified size * and capacity, along with a look-ahead buffer positioned after the main buffer. * * Key features include: * - Automatic buffer rotation to efficiently handle continuous data streams * - Capacity management to prevent buffer overflows * - Look-ahead buffer support for parsers or processors that need to peek ahead * - STL-compatible iterators for standard algorithm compatibility * - Automatic conversion to string_view for string operations

Den här typen av lösningar görs knappt i andra språk. Varför kan man undra men det handlar ju inte om att det inte går.

Vad är det med den lösningen som inte går att göra i andra språk?

Permalänk

@klk Efter att ha läst dina klagomål om och om igen där du säger att "si och så går inte att diskutera med för de fattar inte", har det blivit väldigt tydligt att den gemensamma nämnaren är du. Anledningen till att de inte går att diskutera med är för att du är dålig på att kommunicera. Du lyckas aldrig fatta dig kort. Mycket av det du skriver som att t.ex. chaining ofta gör det svårare att debugga håller nog de flesta med om, men du behöver 3000 ord på dig att göra den poängen.

Permalänk
Medlem
Skrivet av Ingetledigtnamn:

Jag har uppfattat det som att du, när du ser en rad av funktionsanrop (a()->b()->c()->d()), reflexmässigt slår bakut och säger message chaining.

Stämmer, en typ av kod jag brukar söka efter för att tolka problem i kod. Ser jag sådant tittar jag lite mer för att utesluta eventuella misstag från min sida (är medveten om att ingen utvecklare gillar att skriva om kod). Men sedan säger jag till. Det är ett grovt fel av utvecklare att skriva sådan kod.

Skrivet av Ingetledigtnamn:

I många fall har du rätt i att resultatet av detta blir coupling, men det är inte så att en rad av anrop automatiskt innebär den skadliga coupling vi talar om här. Jag försökte påvisa att det inte är de kedjade anropen i sig som skapar coupling utan att det faktum att koden kommer bero på att de olika anropen returnerar ett resultat av en viss typ. Om a() returnerar något som inte har en b-metod kommer det inte kompilera. Om du bryter kedjan till enstaka anrop och stoppar resultaten i temporärer kommer du få precis samma beroenden. Dessa kommer ställa till det vid refactoring även utan att anropen är kedjade.

Coupling är så stort så det är egentligen värt en en eller kanske till och med flera trådar i sig.
Men för att ta en ganska simpel sak och då koppla det till rust. Om en utvecklare skriver ett objekt med kanske 5 medlemmsvariabler. Ibland måste de här variablerna tilldelas med en viss ordning. Hur vet andra programmerare det?
Annat problem med att kjedja anrop så här är att man MÅSTE läsa koden. Personligen kräks jag på sådant. Det går inte att skriva kod utan att veta om hur objekten fungerar internt.
Skillnaden mellan två team där ena teamet följer fasta mönster som gör att de slipper läsa andras kod, jämför dem med annat team där koden är skriven för att läsas. Det är extremt stor skillnad och det första teamet kan skriva enorma mängder utan att tappa fart. Detta medan teamet där koden måste lösas, där tar det stop och de får kämpa med att komma ihåg allt.

Fördelen med att kedja är att det ser snyggt ut och det är lätt att förklara. Skulle du och jag lära ut en skolklass i programmering, du beskriver att kedja och jag försöker förklara problemen. Om det är 30 elever skulle du lätt få med dig 29, kan jag övertyga 1 så är jag glad.
Svåra saker är svåra att lära ut, saknas det något att relatera till. Bakgrunder till varför man löser saker på olika sätt är det i princip omöjligt.

Det är precis som diskussionen vi har här (ursäkta skrytet), vissa saker är otroligt bra tips men få nappar och det beror ofta på att man inte stött på problematiken eller har svårt att relatera till annat som man gjort.

Skrivet av Ingetledigtnamn:

I pipeline-fallet är map, reduce, filter och andra funktioner metoder i container-klassen. De är designade för att man skall kunna göra just pipelining. Jag måste säga att

let evens: Vec<_> = vec![1, 2, 3, 4].into_iter().filter(|x| x % 2 == 0).collect();

är lite elegantare än

std::vector<int> nums = {1, 2, 3, 4}; std::vector<int> evens; std::copy_if(nums.begin(), nums.end(), std::back_inserter(evens), [](int x) { return x % 2 == 0; });

Argumentet "elegant" har i min bok väldigt låg prioritet. Skriver jag kod så skrivs den inte för att läsas, har jag lyckats så kommer koden glömmas bort, ingen kommer någonsin att läsa den koden igen. Så bra är sällan att man lyckas så den dagen koden läses igen så brukar det handla om att det är fel i koden och därför skrivs kod så den är lätt att hitta fel i.

Koden du visar, där är båda exemplen dåliga. Det tar längre tid för någon annan utvecklare att läsa och förstå koden än vad det tog för utvecklaren att skriva koden. Det är också typiska exempel som så ofta används men som inte är realistiska. Normal kod har i princip alltid så mycket mer att hantera än filtrera en list så den tar ut jämna tal.

Det är det svåraste i koden som lösningar anpassas efter. Lätt kod kan i princip skrivas hur som helst, det är nästan svårt att skriva lätt kod så den inte går att förstå.
Samtidigt så reagera jag på annat, du skriver variabkerna nums och evens. Är det för jobbigt att skriva ut hela namn?
För varje förkortning du skriver gör du det svårare för andra utvecklare att läsa din kod.

*tydligare kod*

std::vector<int> vectorNumber = {1, 2, 3, 4}; std::vector<int> vectorEvenNumber; std::copy_if(vectorNumber.begin(), vectorNumber.end(), std::back_inserter(vectorEvenNumber), [](int iNumber) { return (iNumber % 2) == 0; });

Skrivet av Ingetledigtnamn:

Kallar du detta coupling? Visst, det förutsätter att map och filter returnerar en container men det är ett designbeslut man har tagit för att kunna pipelining. Skulle det ställa till det om du vill ändra på map och filter, jajamänsan, men du kommer med största sannolikhet inte behöva göra refactoring på container-klasserna. Detta är kedjade anrop som inte ger coupling, alla beroenden är inom container-klassen.

Det där var INTE coupling, du har en lösning för att räkna ut något lokalt och allt är temporärt (alltså ingen state eller liknande inblandat). Utvecklaren har all information den behöver och det är ok då. Enda kritiken på den typen av lösning är att det kan vara svårläst beroende på hur lång kedjan är och då också svår att debugga. Vad sådan kod normalt behöver är bra kommentarer.

Skrivet av Ingetledigtnamn:

I builder-fallet ser jag inte som en begränsning att returnera self från "del-konstruktorerna". Ok, koden beror på att man gör det, men så gör man i Rust. Coupling, njäe. Förresten, är det inte analogt med att en constructor i C++ implicit returnerar objektet du just initierat. Tycker du det är en begränsning att du inte kan returnera en annan typ från en constructor?

Håller med om att just coupling är svagare men däremot att logik för hur objektet skapas sprids i kod och den typen av kod är svårare att refaktorera. Flexibilitet och reglerna kapslas inte in i objektet utan att utvecklare måste lära sig hur objektet fungerar internt, det är inte bra.

Skrivet av Ingetledigtnamn:

Kör du inte själv med snarlika tekniker där du delegerar till common() att sköta delar av constructor-jobbet? I Rust behöver du inte göra allt i en funktion utan kan bryta upp det i mindre, naturliga bitar.

Om jag eller enligt mig så bra kod för en klass, då är det helt ok att göra det interna jobbet komplext, det gör inget så länge det inte exponeras utåt. Sköter klassen en sak så är det ok. Är det svår kod så dokumentera. Det viktiga är inte att skriva snygg kod i en klass utan som jag skrev ovan, optimalt är att ingen någonsin skall behöva läsa koden i klassen igen.

Permalänk
Medlem
Skrivet av spiksoppa:

@klk Efter att ha läst dina klagomål om och om igen där du säger att "si och så går inte att diskutera med för de fattar inte", har det blivit väldigt tydligt att den gemensamma nämnaren är du. Anledningen till att de inte går att diskutera med är för att du är dålig på att kommunicera. Du lyckas aldrig fatta dig kort. Mycket av det du skriver som att t.ex. chaining ofta gör det svårare att debugga håller nog de flesta med om, men du behöver 3000 ord på dig att göra den poängen.

Är dyslektiker, nämnt det tidigare. Men vill också nämna att det är supersvårt att förklara för en grupp där man inte vet nivån på gruppen.

För c.a. 20 år sedan undervisade jag en del i avancerad C++, företagskurser. Vi hade där en dags introduktionsutbilding innan vi fick lov att undervisa. Halva dagen gick åt att förklara för oss "nya lärare" hur svårt det är att beskriva svåra saker när det varierar bland eleverna och vad de kan ta till sig. Speciellt allvarligt är det när de betalar mycket pengar för att lära sig.

Menar inte att skylla ifrån mig men det är inte lätt, inte ens för personer med tallang i området. Och skall man lyfta en utvecklare så krävs också att den vill det, är helt omöjligt och den sätter sig på tvären.
När jag undervisade så var det motiverade elever, var svårt ändå och det fanns alltid "missnöjda"

Permalänk
Medlem
Skrivet av spiksoppa:

Ena stunden klagar du på att Rust saknar features (överlagring, konstruktorer etc.) och nu klagar du på att unit testing är inbyggt?

Och du förstår inte varför?
testning har inget med språket att göra, varför packa in det?

Skrivet av spiksoppa:

Vad är det med den lösningen som inte går att göra i andra språk?

Inget, för jag skrev just det. Det är en lösning som lätt görs i andra språk också men försök hitta sådant i andra språk?

Permalänk
Skrivet av klk:

Är dyslektiker, nämnt det tidigare. Men vill också nämna att det är supersvårt att förklara för en grupp där man inte vet nivån på gruppen.

Problemet är inte att du skriver dåligt med avseende på grammatik eller stavning. Problemet är att du inte lyckas föra ett sammanhängande logiskt argument. Du försöker argumentera från A -> B men istället för att göra det direkt så pratar du först om ÅÄÖZYG innan du hamnar på B. När du väl kommit till B (efter 30 sidor meddelanden som i den här tråden) så har du lyckats frustrera mig med alla utsvängningar på ÅÄÖZYG att jag bara tänker "jaha du ville bara ta argumentet A -> B, säg det då!".

Permalänk
Medlem
Skrivet av spiksoppa:

Problemet är inte att du skriver dåligt med avseende på grammatik eller stavning. Problemet är att du inte lyckas föra ett sammanhängande logiskt argument. Du försöker argumentera från A -> B men istället för att göra det direkt så pratar du först om ÅÄÖZYG innan du hamnar på B. När du väl kommit till B (efter 30 sidor meddelanden som i den här tråden) så har du lyckats frustrera mig med alla utsvängningar på ÅÄÖZYG att jag bara tänker "jaha du ville bara ta argumentet A -> B, säg det då!".

Vet du hur det är att prata med 5 stycken samtidigt där alla 5 försöker "sätta dit" dig

Alltså skrivet med en smula ironi, Det är ok att tycka jag skriver dumheter eller blandar.
Och det är också en bra teknik om man vill lära sig själv. Tror jag något är rätt, hoppa då in i en varggrop där andra har helt andra åsikter och försök försvara vad man tror är rätt. Då får man lära sig om argumenten håller.

Det här är långt ifrån den första varggropen jag hoppat in i

Permalänk
Skrivet av klk:

Och du förstår inte varför?
testning har inget med språket att göra, varför packa in det?

Vad är det för dogmatisk attityd? Om jag vill skriva ett unit test kan jag göra det direkt utan importera ett bibliotek. Du gillar ju inte att använda externa bibliotek heller så ska jag tolka det som att du inte unit testar eller som att du handkodar unit test biblioteket själv?

Skrivet av klk:

Inget, för jag skrev just det. Det är en lösning som lätt görs i andra språk också men försök hitta sådant i andra språk?

Vad är det du faktiskt försöker säga? Om det nu går att göra i andra språk, vad är då problemet? Att det saknas exempel?

Permalänk
Medlem
Skrivet av spiksoppa:

Vad är det för dogmatisk attityd? Om jag vill skriva ett unit test kan jag göra det direkt utan importera ett bibliotek. Du gillar ju inte att använda externa bibliotek heller så ska jag tolka det som att du inte unit testar eller som att du handkodar unit test biblioteket själv?

Konkurrens, varför skulle just testbiblioteket i rust vara bäst?
Stämmer annars att jag inte unittestar

Skrivet av spiksoppa:

Vad är det du faktiskt försöker säga? Om det nu går att göra i andra språk, vad är då problemet? Att det saknas exempel?

För att det inte görs. Att det går att göra på papperet är inte samma sak

Om någon älskar cyklar, annan gillar att köra bil. Ni argumenterar för hur man bäst tar sig till en stad 10 mil bort. Det går att cykla dessa tio mil men det görs normalt inte

Permalänk
Skrivet av klk:

Och det är också en bra teknik om man vill lära sig själv. Tror jag något är rätt, hoppa då in i en varggrop där andra har helt andra åsikter och försök försvara vad man tror är rätt. Då får man lära sig om argumenten håller.

Jag tolkar det mer som att du försöker visa andra hur bra du är och att få "skryta" (ord som du använt upprepade gånger) om kod du har skrivit. Jag har heller aldrig sett i tråden att du har tagit till dig av information. Du säger ofta saker som objektivt sett är felaktiga och sen när någon rättar dig så ignorerar du det och hoppar vidare till ett annat ämne, lite som en trollkarl (yrkestips om du tröttnar på programmering ).

Permalänk
Datavetare
Skrivet av klk:

Kan de vara så att utvecklare i rust inte använder debugger eller inte alls lika mycket och orsaken till det är att språket har dessa hinder i sig. Smäller det inte lika ofta är det kanske inte det verktyget man lär sig mer än när det blir nödvändigt?

Kan inte tala för andra, jag använder inte debuggern i mindre utsträckning i Rust än i t.ex. C++. Däremot är en del saker som skulle resulterat i en debug-session i t.ex. C++ saker som Rust kommer peka ut explicit och därmed göra buggen uppenbar.

Skrivet av klk:

Ja, är medveten om att det i rust som i så många andra program går att "stänga av saker". Det borde väl till och med att koda assembler i rust precis som det går att göra i C/C++ och andra språk med gissar jag.
Men för att stänga av saker i språk, frångå principerna. Där är min erfarenhet att det skall väldigt mycket till innan någon gör det. Knappt att jag har sett det.
För flera år sedan jobbade jag med en del C# utvecklare, samtliga mina förslag på att försöka lösa problem "smartare" med då runda hur man normalt kodar i C# ratades. Att göra "black box" lösningar var det tvärnit för.

Att använda "unsafe" är inte att "kringgå principer". "unsafe" finns där av en väldigt specifik orsak och det finns en rad fall där det är helt rätt att använda detta. T.ex. om man anropar in i C/C++ kod eller interagerar med minnesmappad I/O.

Stora fördelen med att ha det opt-in är att en rad rätt vanliga C/C++ buggar är inte möjliga i safe Rust (kompilerar inte). Så om man ändå har en sådan bug i sitt program vet man att den buggen måste ligga i något som är "unsafe". Det minskar normalt sökytan enormt -> går mycket snabbare att lokalisera felet.

Svårt att se någon nackdel alls med detta. Bjarne m.fl. verkar inte heller se ett problem och man vill ju jobb mot att även C++ ska fungera mer på detta sätt i framtiden.

Skrivet av klk:

För mig är det inte något possitivt att läsa. Enligt mig är det viktigt att utvecklare lär sig och framför allt lär sig vad som händer när de gör sönder koden. Helst innan koden går sönder hos kund.
När saker går sönder, det är då man lär sig som mest.
Programmerare som aldrig slitit med skitkod eller trasslat in sig, tveksamt om de ens kan kalla sig för programmerare.

I normalfallet håller jag helt med här. Finns absolut inget självändamål att ha 100 % branch/state/line-coverage.

I detta specifika fall skrevs koden till något som skulle certifieras till högsta DO-178C nivån (avionics industrin), där det är ett hårt krav att man kan bevisa att man testat precis alla tänkbara fall.

Att alltid göra detta fungerar inte, är skitdyrt att utveckla sådan programvara. Poängen här var: om man drar TDD till sin spets visade det sig, i alla fall i detta specifika fall, hur otroligt många problem man normalt stöter på i ett projekt av den storleken och komplexitet som helt enkelt redan fångats av testing innan man ens kör första "riktiga" fallet.

Skrivet av klk:

Desto mer jag lär mig om rust, det går åt andra hållet. Har de byggt in sådant också... Vet att en del som kodat rust och byter till annat kritiserar rust för att det blir så mycket "skräp" och jag börjar förstå varför.
Samma fenomen finns i frontend och javascript. Förr gjordes en frontend med lite javascript och några html sidor. Idag är minsta lilla skitlösning flera megabyte med bibliotek och annat.

En, av många saker, som är en stor WTF i C och C++ är att man vid designen av dessa språk inte hade internet, man hade inte lika stora projekt i genomsnitt som idag etc. Att inte ha ett väldefinierat byggsystem, test-ramverk, benchmark-ramverk etc är idag ett rätt stort problem.

Personligen använder jag CMake till C/C++ om jag gör något från scratch samt Google Test och Google Benchmark för dessa saker. Dock långtifrån någon standard och är rätt mycket mer tragglande att en få igång "hello-world" p.g.a. det jämfört med Rust, Go, C# m.fl. Att använda något likt Visual Studio är ingen lösning, det är ett hack som låser en till Windows!

Time-to-hello-world har visat sig vara en viktigare metric än man kanske kan tro och tyvärr levererar äldre språk som C och C++ inte på någon vidare nivå här.

Skrivet av klk:

Det senaste jag satt med, i början på veckan var en liten grej för att parsa stora filer.
Kommentar från koden

* \brief A flexible buffer class for managing linear data with look-ahead capabilities. * * The line class provides a buffer implementation that supports efficient reading, * writing, and processing of linear data. It maintains a main buffer of specified size * and capacity, along with a look-ahead buffer positioned after the main buffer. * * Key features include: * - Automatic buffer rotation to efficiently handle continuous data streams * - Capacity management to prevent buffer overflows * - Look-ahead buffer support for parsers or processors that need to peek ahead * - STL-compatible iterators for standard algorithm compatibility * - Automatic conversion to string_view for string operations

Den här typen av lösningar görs knappt i andra språk. Varför kan man undra men det handlar ju inte om att det inte går.

Skulle säga att det du listar ovan är saker som både Rust, men även Go, också är väldigt starka på. Sådana saker är inte helt ovanliga i C++, bortsett från hjärndött sega kompileringstider är ju saker som boost-spirit rätt mycket designat för detta.

Men utmaningarna här är också saker som Rust och Go också har stora styrkor i.

Angående det sista är ju string_view helt klart något bra. Men det känns tyvärr långt mer som en "bolt-on" i C++ jämfört med Rust där "str" fyller samma syfte och dess användning känns (och är) långt mer integrerat i språket. Stränghantering i alla "moderna" språk är typiskt UTF-8 native, inklusive Rust och Go, så sådan hantering är enklare och mer naturligt där.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av spiksoppa:

Jag tolkar det mer som att du försöker visa andra hur bra du är och att få "skryta" (ord som du använt upprepade gånger) om kod du har skrivit. Jag har heller aldrig sett i tråden att du har tagit till dig av information. Du säger ofta saker som objektivt sett är felaktiga och sen när någon rättar dig så ignorerar du det och hoppar vidare till ett annat ämne, lite som en trollkarl (yrkestips om du tröttnar på programmering ).

Kan du ta ett specifikt fall där du vet med 100% fall att jag har fel, jag är ändå noga med att läsa vad andra skriver men kan låta bli och ge mig in i diskussionen den söker efter. Oftast beror det på att jag ser det som lönlöst, antingen kan jag inte förklara min åsikt, jag ser det inte som intressant eller personen har ingen avsikt att diskutera sakligt.

Sedan har jag lång erfarenhet, som de flesta så lär man sig, ingen konstighet med det. För ett tag sedan försökte jag uppskatta hur mycket C++ kod jag skrivit i mitt liv. Det är minst 4 miljoner rader kod, förutom det har jag minst en halv miljon javascript kod. Kodat annat med men där är det mindre.

Har någon skrivit så mycket kod och/eller läst massor av annan kod så lär man sig se problem.

Permalänk
Skrivet av klk:

Konkurrens, varför skulle just testbiblioteket i rust vara bäst?

Kan du konkret säga vad som är problemet med unit test ramverket i Rust? Det finns massa crates som bygger på det: https://crates.io/keywords/unit-test

Skrivet av klk:

Stämmer annars att jag inte unittestar

Bruh... Jobbar du med spelprogrammering? Det är enda domänen jag känner till där man ofta undviker unit test. Du argumenterar ofta att kodkvalitet är viktigt och att andra inte vill lägga tid på det (som jag tolkat tidigare meddelanden). Hur förklarar du denna diskrepans?

Skrivet av klk:

För att det inte görs. Att det går att göra på papperet är inte samma sak

Om någon älskar cyklar, annan gillar att köra bil. Ni argumenterar för hur man bäst tar sig till en stad 10 mil bort. Det går att cykla dessa tio mil men det görs normalt inte

Fair enough. Du får nog visa din kod så att vi andra kan förstå vad det är som händer i funktionen. Lite XY, vad är det för problem du faktiskt löser?

Permalänk
Medlem
Skrivet av Yoshman:

Skulle säga att det du listar ovan är saker som både Rust, men även Go, också är väldigt starka på. Sådana saker är inte helt ovanliga i C++, bortsett från hjärndött sega kompileringstider är ju saker som boost-spirit rätt mycket designat för detta.

Kort svar (får återkomma i det andra)
Men repeterar, det är absolut inget unikt med just C++ och den lösningen. Den är så enkel att jag aldrig hade försökt leta men eftersom vi har den här tråden så gjorde jag det ändå, tekniken är exempelvis vanlig vid vad man ibland kallar för "pull parsers" tror jag (osäker). För egen del är det bara en smart och enkel teknik för att lösa något när minnet inte räcker.

Förr var det så här utvecklare tänkte, när det inte fanns färdiga lösningar fick man lösa saker själv och det kan vara en av orsakerna till varför det är så svårt att hitta udda lösningar i språken idag.

Permalänk
Medlem
Skrivet av spiksoppa:

Bruh... Jobbar du med spelprogrammering? Det är enda domänen jag känner till där man ofta undviker unit test. Du argumenterar ofta att kodkvalitet är viktigt och att andra inte vill lägga tid på det (som jag tolkat tidigare meddelanden). Hur förklarar du denna diskrepans?

Jag unittestar inte för det är för dåligt (osäkert, och gör om koden till sirap sett till ändringar). Men det är en annan diskussion

Spelprogrammerare har jag åsikter om

Permalänk
Medlem
Skrivet av klk:

...
Samtidigt så reagera jag på annat, du skriver variabkerna nums och evens. Är det för jobbigt att skriva ut hela namn?
För varje förkortning du skriver gör du det svårare för andra utvecklare att läsa din kod.

*tydligare kod*

std::vector<int> vectorNumber = {1, 2, 3, 4}; std::vector<int> vectorEvenNumber; std::copy_if(vectorNumber.begin(), vectorNumber.end(), std::back_inserter(vectorEvenNumber), [](int iNumber) { return (iNumber % 2) == 0; });

...

Jag skulle nog vilja påstå att det exemplet på "tydligare kod" inte hjälper läsbarheten, det blir bara för explicit och långrandigt. Ser inga problem med att korta ner variabelnamnen till:

vNumber och vEvenNumber

då definitionerna förklarar detaljerna och det bör inte ta mer än 15 sekunder för hjärnan att förstå vilka premisser koden i detta projekt är skriven. Jag skulle till och med stå ut med att använda pluraländelsen som implicit för en vektor.

Numbers och EvenNumbers

Men nu kanske jag närmar mig gränsen för vad som är tolererbart.
Från en som alltid döper iterationsvariablen till "i".

Permalänk
Datavetare
Skrivet av klk:

Kan du ta ett specifikt fall där du vet med 100% fall att jag har fel, jag är ändå noga med att läsa vad andra skriver men kan låta bli och ge mig in i diskussionen den söker efter. Oftast beror det på att jag ser det som lönlöst, antingen kan jag inte förklara min åsikt, jag ser det inte som intressant eller personen har ingen avsikt att diskutera sakligt.

Sedan har jag lång erfarenhet, som de flesta så lär man sig, ingen konstighet med det. För ett tag sedan försökte jag uppskatta hur mycket C++ kod jag skrivit i mitt liv. Det är minst 4 miljoner rader kod, förutom det har jag minst en halv miljon javascript kod. Kodat annat med men där är det mindre.

Har någon skrivit så mycket kod och/eller läst massor av annan kod så lär man sig se problem.

En specifik sak som kommit upp rätt mycket i denna tråd från din sida är att C++ "är mer flexibelt i att hantera minne".

Skulle säga att du har 100,0 % fel i detta fall om vi ställer någon av C, Rust, Go och C# på andra sidan (det är garanterat en längre lista, men det är de språk jag kan i tillräcklig detalj för att göra utsagan).

Specifikt C och Rust borde vara rätt uppenbart att man kan inkludera här givet att de likt C++ specifikt är designade som systemspråk. Go och C# har specifika funktioner gör att kunna jobba med C ABI samt direkt hantera minnesmappad I/O (Java må kunna göra det, men där behöver man gå mer utanför "normal kod" och är mer en förlängning av att man kan jobba mot C-bibliotek).

Omvända gäller också här. Ingen är "bättre" här egentligen, de ger motsvarande funktion. Rust, Go och C# har dock fördelen att om man lyckas krascha sitt program på ett sätt som rimligen beror på misstag i lågnivåhantering av minne så måste den ligga i något markerat "unsafe". I C och C++ kan ett sådant problem tyvärr vara precis var som helst då all kod är "unsafe" (något potentiellt båda språken kan komma att ändra, C om TrapC blir vägen framåt och finns flera förslag för C++ med motsvarande resultat).

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av mc68000:

Jag skulle nog vilja påstå att det exemplet på "tydligare kod" inte hjälper läsbarheten, det blir bara för explicit och långrandigt. Ser inga problem med att korta ner variabelnamnen till:

vNumber och vEvenNumber

då definitionerna förklarar detaljerna och det bör inte ta mer än 15 sekunder för hjärnan att förstå vilka premisser koden i detta projekt är skriven. Jag skulle till och med stå ut med att använda pluraländelsen som implicit för en vektor.

Numbers och EvenNumbers

Men nu kanske jag närmar mig gränsen för vad som är tolererbart.
Från en som alltid döper iterationsvariablen till "i".

När du skriver läsbarhet, för "vem" menar du då? Vad tycker du är problematiskt med att man direkt ser att det är en vector om variabeln börjar man klassnamnet, varför är det otydligt?
Är det inte viktigt för att förstå koden och snabbt se vad det är för objekt

Permalänk
Datavetare
Skrivet av klk:

Jag unittestar inte för det är för dåligt (osäkert, och gör om koden till sirap sett till ändringar). Men det är en annan diskussion

Spelprogrammerare har jag åsikter om

Ett vanligt misstag, och ett misstag jag gissar alla initialt kommer göra, är att de skriver unit-tester som testar en specifik implementation och inte ett förväntat beteende av ett API. Detta gör refactoring till ett rent helvete...

En stor varningssignal på detta är väldigt stor användning av mocks. Finns absolut fall där dessa behövs, men i bra unit-tester tenderar det vara relativt ovanligt med mocks.

Att spel är dåliga på att unit-testa tror jag delvis är en konsekvens av att spelmotorer är lite av sitt eget OS med sina egna regler där det ofta finns en lite onödigt stor barriär för att lätt kunna få in unit-tester.

Men är absolut möjligt att använda unit-tester även i spel och har förstahandsinfo på att det kan ha stora fördelar i att testa icke-triviala subsystem i spel.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

En specifik sak som kommit upp rätt mycket i denna tråd från din sida är att C++ "är mer flexibelt i att hantera minne".

Kan det vara så att vi har olika betydelse i ordet "flexibelt"
När jag skriver flexibelt så menar jag för programmeraren, att det är fritt. Jag kan casta om och göra som jag vill.
Andra språk har hinder för det och det upplever jag som mindre flexibelt.

Det finns saker i C++ som jag ogillar, använder sällan smart pointers och de nya orden för att casta är sällsynta i min kod, tänker då dessa static_cast, const_cast mm.

Permalänk
Medlem
Skrivet av klk:

När du skriver läsbarhet, för "vem" menar du då? Vad tycker du är problematiskt med att man direkt ser att det är en vector om variabeln börjar man klassnamnet, varför är det otydligt?
Är det inte viktigt för att förstå koden och snabbt se vad det är för objekt

Därför att en ständig repetition av "vector" tar bort fokus från den logiska biten av koden. Hjärnan får ständigt traggla typer när den egentligen letar efter ett felaktigt minustecken, ett felaktigt argumentnamn, eller en ofullständig beräkning av en variabel. Att ha med typen i variabelnamnet (som kortform) har sina fördelar ja, men det blir lätt en explicit börda, speciellt om koden skall hålla sig inom 80-99 kolumner.

Permalänk
Medlem
Skrivet av Yoshman:

Ett vanligt misstag, och ett misstag jag gissar alla initialt kommer göra, är att de skriver unit-tester som testar en specifik implementation och inte ett förväntat beteende av ett API. Detta gör refactoring till ett rent helvete...

Och då tillägger jag att det är en typ av test som "min" kod är full av har fått lära mig att det ibland kallas för regressions tester.

Nackdelen med unittester är precis som du beskrev och det är "extra" kod som inte tillför något vettigt.

Vid "regressions testning" är det mycket mer att arbeta med produktionskod. Hela applikationen förbättras och blir mer flexibel istället för att låsa koden och göra projektet svårarbetat.
Vet kod man knappt vågat röra i just på grund av att då kraschade tester och det var knappt någon som förstod hur allt hängde samman. Unittester kan innebära katastrof.

Kan ha fel om namn på testningen, frågade LLM och fick nog över 20 olika namn på testmetodiker

Permalänk
Skrivet av klk:

Kan det vara så att vi har olika betydelse i ordet "flexibelt"
När jag skriver flexibelt så menar jag för programmeraren, att det är fritt. Jag kan casta om och göra som jag vill.
Andra språk har hinder för det och det upplever jag som mindre flexibelt.

Det finns saker i C++ som jag ogillar, använder sällan smart pointers och de nya orden för att casta är sällsynta i min kod, tänker då dessa static_cast, const_cast mm.

Det här förklarar ganska mycket och förklarar varför du är så mån att argumentera för att det inte finns något problem med minnessäkerhet i C++. Bjarne, Herb Sutter och i stort sett alla andra framträdande C++ utvecklare som jag lyssnat på förespråkar smart pointers, static_cast, undvika reinterpret_cast etc. Det låter som att du skriver C++ som det skrevs för 20 år sen. Det finns inget "rätt" eller "fel" i detta men de flesta vill nog inte skriva kod som du skriver. Du skriver inte heller unit tester...

Permalänk
Datavetare
Skrivet av klk:

Kan det vara så att vi har olika betydelse i ordet "flexibelt"
När jag skriver flexibelt så menar jag för programmeraren, att det är fritt. Jag kan casta om och göra som jag vill.
Andra språk har hinder för det och det upplever jag som mindre flexibelt.

Det finns saker i C++ som jag ogillar, använder sällan smart pointers och de nya orden för att casta är sällsynta i min kod, tänker då dessa static_cast, const_cast mm.

Fast du kan ju fritt cast:a i alla de språk jag nämnde ovan m.h.a. unsafe. Rusts "std::mem" har en del hjälpfunktioner för att göra sådant, t.ex. std::transmute som rätt mycket är reinterpret_cast<> (och likt den senare är det något man bör undvika...).

Go har utöver fri hantering i "unsafe" även "safe" varianter för att t.ex. ta 4 bytes och tolka dem som float32.

Så vidhåller att du är helt ute och cyklar på denna punkt.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av mc68000:

Därför att en ständig repetition av "vector" tar bort fokus från den logiska biten av koden. Hjärnan får ständigt traggla typer när den egentligen letar efter ett felaktigt minustecken, ett felaktigt argumentnamn, eller en ofullständig beräkning av en variabel. Att ha med typen i variabelnamnet (som kortform) har sina fördelar ja, men det blir lätt en explicit börda, speciellt om koden skall hålla sig inom 80-99 kolumner.

Menar du då att du skriver kod med namn efter domänen (användaren)

Mitt tips till det är att alltid göra vad du kan för att lyfta bort domänen från koden. Den del där domänen måste in bör göras så tunn som möjligt. Så fort utvecklare måste ha domänkunskap för att hantera koden blir det en extra tröskel

Permalänk
Medlem
Skrivet av Yoshman:

Så vidhåller att du är helt ute och cyklar på denna punkt.

Om jag tar ett exempel. Om jag i C++ plussar en pointer, då vet kompilatorn storleken på objektet och vet hur långt pekaren skall flyttas, fungerar det så i rust med?

Skrivet av Yoshman:

Fast du kan ju fritt cast:a i alla de språk jag nämnde ovan m.h.a. unsafe. Rusts "std::mem" har en del hjälpfunktioner för att göra sådant, t.ex. std::transmute som rätt mycket är reinterpret_cast<> (och likt den senare är det något man bör undvika...).

I C++ behöver jag inte massa metoder, jag kan gå direkt på data
reinterpret_cast använder jag sällan