På vilket sätt kommer man bättre åt hårdvaran med C jämfört med C++?

Trädvy Permalänk
Medlem
Plats
Örnsköldsvik
Registrerad
Jun 2008

På vilket sätt kommer man bättre åt hårdvaran med C jämfört med C++?

Detta är ingen klassisk C vs C++. Vi vet att det man kan göra i C++, kan man göra i C och det man kan göra i C kan man göra i C++. Vi vet också att man kan programmera OOP inom C också via funktionspekare och structs.

Men.....
I många läroböcker så skrivs det att man kan komma åt hårdvaran bättre med C än i C++. Kan någon ge något exempel?
Det är troligtvis därför C används mer än C++.

Referens: Vägen till C av Ulf Bilting och Jan Skansholm - baksidan.

| CPU: MMX 200 MHz Intel Pentium I| GPU: Voodo2 3dfx 8 Mb| RAM: SDRAM 32 Mb 133 Mhz | PSU: 3V fläkt 2W | Chassi: HP Vectra VE 5| Skärm: HP Ergo 1024| HDD: Toshiba 2033 MB | OS: Windows 95 B | Mus: HP |

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Jun 2007

Det beror väl på vad man syftar på. C som språk har ingen fördel mot C++ när det gäller att skriva hårdvarunära kod, eftersom C inte har några språkkonstruktioner som gör det bättre lämpat jämfört med C++. Däremot så är C ett vanligt språk bland inbyggda system och andra system med begränsade resurser, eftersom det är ett relativt enkelt språk att implementera stöd för samtidigt som det är kraftfullt och populärt. C++ är ett mycket större och mer komplicerat språk, så det krävs mer ansträngning att implementera stöd för det.

När vi snackar moderna datorer och operativsystem så betyder hårdvarunära programmering istället att man skriver drivrutiner för hårdvara. Och t.ex. Linux-kärnan har inte stöd för att skriva moduler i C++, medan Windows tillåter att man skriver drivrutiner i C++. Båda har dock stöd för C.

Trädvy Permalänk
Medlem
Registrerad
Sep 2006

I DOS har C direktstöd för I/O. I Win 3 krävdes .386-drivare och i NT krävs .SYS-drivare. I linux krävs en device driver som är betydligt enklare (att skriva) än en NT-drivare.
Har aldrig sett ett C++-program som drekt accessar I/O (H/W) men C++ borde ju inte utesluta det utan det är O/S som tillåter eller inte, via drivare. C i embeddedsystem har alltid, som jag sett, full tillgång till I/O (H/W).

Trädvy Permalänk
Medlem
Plats
Örnsköldsvik
Registrerad
Jun 2008
Skrivet av perost:

Det beror väl på vad man syftar på. C som språk har ingen fördel mot C++ när det gäller att skriva hårdvarunära kod, eftersom C inte har några språkkonstruktioner som gör det bättre lämpat jämfört med C++. Däremot så är C ett vanligt språk bland inbyggda system och andra system med begränsade resurser, eftersom det är ett relativt enkelt språk att implementera stöd för samtidigt som det är kraftfullt och populärt. C++ är ett mycket större och mer komplicerat språk, så det krävs mer ansträngning att implementera stöd för det.

När vi snackar moderna datorer och operativsystem så betyder hårdvarunära programmering istället att man skriver drivrutiner för hårdvara. Och t.ex. Linux-kärnan har inte stöd för att skriva moduler i C++, medan Windows tillåter att man skriver drivrutiner i C++. Båda har dock stöd för C.

Då hur mycket mindre blir ett C program jämfört med ett C++ program om dem gör samma sak?

Skickades från m.sweclockers.com

| CPU: MMX 200 MHz Intel Pentium I| GPU: Voodo2 3dfx 8 Mb| RAM: SDRAM 32 Mb 133 Mhz | PSU: 3V fläkt 2W | Chassi: HP Vectra VE 5| Skärm: HP Ergo 1024| HDD: Toshiba 2033 MB | OS: Windows 95 B | Mus: HP |

Trädvy Permalänk
Moderator
Plats
Linköping
Registrerad
Apr 2004
Skrivet av heretic16:

Då hur mycket mindre blir ett C program jämfört med ett C++ program om dem gör samma sak?

Skickades från m.sweclockers.com

Med samma kod blir de förmodligen ungefär lika stora. Det som avses med "mindre" är att c jämfört med c++ har färre finesser (klasser, felhantering, överlagring, mallar, o.s.v.) och ett mindre standardbibliotek. Vad det ger för effekt på hur man skriver program och hur stora de blir efter kompilering är en annan fråga.

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Mar 2008
Skrivet av heretic16:

I många läroböcker så skrivs det att man kan komma åt hårdvaran bättre med C än i C++. Kan någon ge något exempel?

Många läroböcker? Har du mer än ett exempel? Baksidan av vägen till C säger

C har möjligheter som saknas i de flesta andra programmeringsspråk. Speciellt gäller det språkkonstruktioner som tillåter programmeraren att komma ”nära” processor, minne och externa enheter.

Den säger inte att C är mer hårdvarunära än C++ för det är det inte.

C++ är nästan ett strikt superset av C och båda språken fungerar på samma sätt när det gäller hårdvarutillgång.

Det finns många anledningar till att C är mer vanligt i operativsystem och embedded system. C++ är ett mycket stort språk vilket ställer till med problem. När de flesta numera mogna operativsystemen började utvecklas på 80-90 talet fanns det inte så många mogna C++ kompilatorer och C++ var fortfarande ett nytt obeprövat språk.

En av Linus Torvalds favoritsysselsättningar är att svära på gcc utvecklarna. Det är många buggar i linux kerneln som i efterhand visat sig vara buggar i kompilatorn. Eftersom C++ är så mycket större finns det också mycket mer buggar i g++. Varje gång en linux distribution uppdaterar till den senaste versionen av gcc hittas det en bunt regressions som gör att kod som borde kompileras inte gör det. De buggarna brukar vanligtvis vara i g++ kod för kompilatorn och språket är mer komplex.

Ett krav i designen av C++ var att språket inte skulle vara långsammare än C men det gäller bara språket i sig, inte nödvändigtvis implementation. T.ex. var det inte förrän GCC-3 släppt 2001 som g++ var ungefär likvärdig med gcc i prestanda. Prestanda är ofta viktigt i lågnivåkod så C++ undveks.

C är ett litet språk och det är mycket enklare att porta en C kompilator till en ny arkitektur än en C++ kompilator. Embedded system använder ofta mer obskyra arkitekturer där det kanske inte finns någon C++ kompilator tillgänglig och om det finns är den troligen mindre testad och har fler buggar.

Trädvy Permalänk
Medlem
Registrerad
Sep 2006

Storleken på programkod (exefiler + bibliotek) mellan C och C++ kan variera kraftigt. Att ett C++ program är 100% större (kräver mer minne) är inte ovanligt då det länkar in klassbibliotek och kräver dll:er. Exekveringen är normalt långsammare i C++ än i C pga. att koden måste passera klassbiblioteken. En försämring av exekveringstid på 50% är inte ovanlig. Det gamla MFC var hopplöst men modernare .NET är bättre. Har portat om C++ till C pga. prestandaproblem.

Trädvy Permalänk
Moderator
Plats
Linköping
Registrerad
Apr 2004
Skrivet av lassep1l1s:

Storleken på programkod (exefiler + bibliotek) mellan C och C++ kan variera kraftigt. Att ett C++ program är 100% större (kräver mer minne) är inte ovanligt då det länkar in klassbibliotek och kräver dll:er. Exekveringen är normalt långsammare i C++ än i C pga. att koden måste passera klassbiblioteken. En försämring av exekveringstid på 50% är inte ovanlig. Det gamla MFC var hopplöst men modernare .NET är bättre. Har portat om C++ till C pga. prestandaproblem.

Fast det är ju i så fall ett problem med hur man använder c++ snarare än ett problem med språket i sig. Man kan som sagt ofta använda c++ som c (och länka helt statiskt om man vill). Sedan är det ju inte säkert stora standardbibliotek och liknande gör saker långsammare; om de hyfsat väl passar för att lösa något problem man har är de väl ofta ganska väl implementerade.

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011
Skrivet av lassep1l1s:

Storleken på programkod (exefiler + bibliotek) mellan C och C++ kan variera kraftigt. Att ett C++ program är 100% större (kräver mer minne) är inte ovanligt då det länkar in klassbibliotek och kräver dll:er. Exekveringen är normalt långsammare i C++ än i C pga. att koden måste passera klassbiblioteken. En försämring av exekveringstid på 50% är inte ovanlig. Det gamla MFC var hopplöst men modernare .NET är bättre. Har portat om C++ till C pga. prestandaproblem.

Om du ställer två personer som verkligen kan programmera C++ och C mot varandra och ger dem samma uppgift så kommer C++ bli det snabbare alternativet i genomsnitt. Finns helt enkelt tekniker man kan använda i C++ som ger kompilator optimeringsmöjligheter som inte finns i C. Naturligtvis är det rent tekniskt möjligt att handoptimera C-koden så den blir identisk med C++, men det skulle ofta resultera i kod som är hopplös att underhålla.

Notera att jag skrev "i genomsnitt", i de flesta fall skulle programmen prestera i stort sett identiskt.

Ett exempel, sortering är snabbare i C++ därför att kompilatorn kommer göra s.k. "template specialization" av std::sort just för "sekvens av heltal" och går därför att göra optimeringar i form av direkta anrop till funktion som jämför element, specialiserad funktion som byter plats på två element etc. I C kan man också skriva generella algoritmer, men polymorfismen får man hantera via indirekta anrop (ungefär dubbelt så dyra som direkta anrop och svårare för en CPU att "gissa") och generell funktion som byter plats på två element.

Kör du detta ser du att sortering av heltal i C++ är 50%-100% snabbare. Har inget med underliggande algoritmen i std::sort vs qsort att göra utan är en ren effekt av det jag skrev ovan.

#include <stdlib.h> #include <algorithm> #include <vector> std::vector<int> seqMake(size_t cnt) { std::vector<int> seq; for (size_t i = 0; i < cnt; i++) { seq.push_back(rand()); } return seq; } static int intCmp(const void * a, const void * b) { return *(int *)a - *(int *)b; } int main(int argc, char *argv[]) { auto seq = seqMake(10000000); if (argc > 1) { qsort(seq.data(), seq.size(), sizeof seq[0], intCmp); } else { std::sort(std::begin(seq), std::end(seq)); } }

Däremot går faktiskt inte C++ att använda för t.ex. OS, det går att använda en delmängd av C++ även i en OS kärna men där har ni nog den stora anledningen varför C än i dag i praktiken är det enda man skriver OS med. T.ex. så är undantag (eng. exceptions) totalt förkastligt i en OS-kärnan och går inte att ha sådana på ett tillförlitligt sätt där.

Är däremot fullt möjligt att använda en delmängd av C++ och göra t.ex. drivers till Linux (man skulle aldrig få in något sådant i kernel.org kärnan men det är tekniskt möjligt att skriva). Enda restriktionen är att man inte får använda något ur standardbiblioteket, man får inte använda RTTI, exceptions och liknande samt att det gränssnitt som exporteras ur modulen måste ha s.k. "C-linkage".

Det sista är ännu en anledning varför man inte använder C++ i OS. I C++ kan en flera funktioner/metoder ha samma namn men olika argument (en form av polymorfism), för att hantera detta i länkare måste då namnet på funktionen "manglas/dekoreras". Hur denna dekorering går till har aldrig standardiseras så om man använder C++ i ett OS gör man OSet beroende av en specifik kompilator!

I C finns standardregler för vilket namn funktioner/variabler får i länksteget -> går att använda olika kompilatorer och ändå garantera kompatibilitet på en specifik plattform.

Sist men absolut inte minst: OS-kärnor och andra komponenter som typiskt lever i >30 år bara måste byggas på teknik som först och främst är stabil. Att nästan inget händer med C är alltså en fördel här. Vidare är det inte möjligt att orsaka några som helst implicita anrop i C, det är väldigt viktigt för OS-kärnor och kringliggande komponenter som används i system som bara inte får gå fel. Är i stort sett hopplöst att bevisa att kod skrivet i språk med implicita anrop, undantag och andra saker som resulterar i att programflödet inte är trivialt.

Ex:

SomeType x = foo("bar");

Hur många anrop och hur många vägar finns det i koden ovan i C? Är trivial, en!
I C++? Tja, kan bli ett anrop som konverterar "bar" till typen som foo() tar med tillhörande anrop till destruktor. Kan bli ett anrop till en casting operator för att konvertera det foo() returnerar till SomeType. Det kanske värsta är: foo() kanske inte alls returnerar utan resulterar i ett undantag.

Vilken av ovan vill du att styrsystem i det flygplan du åker med är utvecklat med? Eller vilket vill du se i din hjärt/lungmaskin under en operationer?

OBS: detta är inte en bashing av C++ utan ett försökt till svar på TS fråga. Skulle välja C++ varje dag i veckan över C om jag fick uppgiften att utveckla ett spel, ett ordbehandlare, ett webbläsare, en webbserver. Typ alla "vanliga" applikationer skulle jag välja C++ över C. Men för OS och för kritiska applikationer är det svårt att slå C än i dag!

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

Trädvy Permalänk
Medlem
Plats
Örnsköldsvik
Registrerad
Jun 2008
Skrivet av Yoshman:

Om du ställer två personer som verkligen kan programmera C++ och C mot varandra och ger dem samma uppgift så kommer C++ bli det snabbare alternativet i genomsnitt. Finns helt enkelt tekniker man kan använda i C++ som ger kompilator optimeringsmöjligheter som inte finns i C. Naturligtvis är det rent tekniskt möjligt att handoptimera C-koden så den blir identisk med C++, men det skulle ofta resultera i kod som är hopplös att underhålla.

Notera att jag skrev "i genomsnitt", i de flesta fall skulle programmen prestera i stort sett identiskt.

Ett exempel, sortering är snabbare i C++ därför att kompilatorn kommer göra s.k. "template specialization" av std::sort just för "sekvens av heltal" och går därför att göra optimeringar i form av direkta anrop till funktion som jämför element, specialiserad funktion som byter plats på två element etc. I C kan man också skriva generella algoritmer, men polymorfismen får man hantera via indirekta anrop (ungefär dubbelt så dyra som direkta anrop och svårare för en CPU att "gissa") och generell funktion som byter plats på två element.

Kör du detta ser du att sortering av heltal i C++ är 50%-100% snabbare. Har inget med underliggande algoritmen i std::sort vs qsort att göra utan är en ren effekt av det jag skrev ovan.

#include <stdlib.h> #include <algorithm> #include <vector> std::vector<int> seqMake(size_t cnt) { std::vector<int> seq; for (size_t i = 0; i < cnt; i++) { seq.push_back(rand()); } return seq; } static int intCmp(const void * a, const void * b) { return *(int *)a - *(int *)b; } int main(int argc, char *argv[]) { auto seq = seqMake(10000000); if (argc > 1) { qsort(seq.data(), seq.size(), sizeof seq[0], intCmp); } else { std::sort(std::begin(seq), std::end(seq)); } }

Däremot går faktiskt inte C++ att använda för t.ex. OS, det går att använda en delmängd av C++ även i en OS kärna men där har ni nog den stora anledningen varför C än i dag i praktiken är det enda man skriver OS med. T.ex. så är undantag (eng. exceptions) totalt förkastligt i en OS-kärnan och går inte att ha sådana på ett tillförlitligt sätt där.

Är däremot fullt möjligt att använda en delmängd av C++ och göra t.ex. drivers till Linux (man skulle aldrig få in något sådant i kernel.org kärnan men det är tekniskt möjligt att skriva). Enda restriktionen är att man inte får använda något ur standardbiblioteket, man får inte använda RTTI, exceptions och liknande samt att det gränssnitt som exporteras ur modulen måste ha s.k. "C-linkage".

Det sista är ännu en anledning varför man inte använder C++ i OS. I C++ kan en flera funktioner/metoder ha samma namn men olika argument (en form av polymorfism), för att hantera detta i länkare måste då namnet på funktionen "manglas/dekoreras". Hur denna dekorering går till har aldrig standardiseras så om man använder C++ i ett OS gör man OSet beroende av en specifik kompilator!

I C finns standardregler för vilket namn funktioner/variabler får i länksteget -> går att använda olika kompilatorer och ändå garantera kompatibilitet på en specifik plattform.

Sist men absolut inte minst: OS-kärnor och andra komponenter som typiskt lever i >30 år bara måste byggas på teknik som först och främst är stabil. Att nästan inget händer med C är alltså en fördel här. Vidare är det inte möjligt att orsaka några som helst implicita anrop i C, det är väldigt viktigt för OS-kärnor och kringliggande komponenter som används i system som bara inte får gå fel. Är i stort sett hopplöst att bevisa att kod skrivet i språk med implicita anrop, undantag och andra saker som resulterar i att programflödet inte är trivialt.

Ex:

SomeType x = foo("bar");

Hur många anrop och hur många vägar finns det i koden ovan i C? Är trivial, en!
I C++? Tja, kan bli ett anrop som konverterar "bar" till typen som foo() tar med tillhörande anrop till destruktor. Kan bli ett anrop till en casting operator för att konvertera det foo() returnerar till SomeType. Det kanske värsta är: foo() kanske inte alls returnerar utan resulterar i ett undantag.

Vilken av ovan vill du att styrsystem i det flygplan du åker med är utvecklat med? Eller vilket vill du se i din hjärt/lungmaskin under en operationer?

OBS: detta är inte en bashing av C++ utan ett försökt till svar på TS fråga. Skulle välja C++ varje dag i veckan över C om jag fick uppgiften att utveckla ett spel, ett ordbehandlare, ett webbläsare, en webbserver. Typ alla "vanliga" applikationer skulle jag välja C++ över C. Men för OS och för kritiska applikationer är det svårt att slå C än i dag!

Så om Linux-kärnan skulle skrivas idag så skulle den ha blivit skriven i C++? Jag förstod inte riktigt vad du menade.

Skickades från m.sweclockers.com

| CPU: MMX 200 MHz Intel Pentium I| GPU: Voodo2 3dfx 8 Mb| RAM: SDRAM 32 Mb 133 Mhz | PSU: 3V fläkt 2W | Chassi: HP Vectra VE 5| Skärm: HP Ergo 1024| HDD: Toshiba 2033 MB | OS: Windows 95 B | Mus: HP |

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011

@heretic16: kan man skriva ett OS i C++? Nej. Men man kan rent teoretiskt skriva ett OS i en delmängd av C++.

Om någon startade ett OS idag, skulle det skrivas i C++? Knappast, än idag är C det nästan självklara valet för att skriva OS-kärnor i.

Och för att svara på din fråga i titeln till denna tråd:
Då detta är tillåtet i C++

uint8_t *ptr = reinterpret_cast<uint8_t*>(0x1234); *ptr = 0x42; // skriv 0x42 till whatever som råkar ligga på adress 0x1234

så är det möjligt att läsa/skriva till minnesmappade enheter precis på samma sätt som i C. Ur den aspekten är C och C++ exakt lika "nära" HW.

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

Trädvy Permalänk
Medlem
Plats
Örnsköldsvik
Registrerad
Jun 2008
Skrivet av Yoshman:

@heretic16: kan man skriva ett OS i C++? Nej. Men man kan rent teoretiskt skriva ett OS i en delmängd av C++.

Om någon startade ett OS idag, skulle det skrivas i C++? Knappast, än idag är C det nästan självklara valet för att skriva OS-kärnor i.

Och för att svara på din fråga i titeln till denna tråd:
Då detta är tillåtet i C++

uint8_t *ptr = reinterpret_cast<uint8_t*>(0x1234); *ptr = 0x42; // skriv 0x42 till whatever som råkar ligga på adress 0x1234

så är det möjligt att läsa/skriva till minnesmappade enheter precis på samma sätt som i C. Ur den aspekten är C och C++ exakt lika "nära" HW.

Så anledningen varför man skriver kärnor i C än i C++ är för att C är "oförrändrat" och därmed är kompilatorn anpassad för CPU:n?

Varför inte skapa en kompilator i C++ som är anpassad för att skriva kärnor? Jag vet att det är mer jobb att skapa en C++ kompilator för en viss CPU än i C. Men när man väl har skapat den så är den klar. Man uppfinner inte hjulet på nytt.

Skickades från m.sweclockers.com

| CPU: MMX 200 MHz Intel Pentium I| GPU: Voodo2 3dfx 8 Mb| RAM: SDRAM 32 Mb 133 Mhz | PSU: 3V fläkt 2W | Chassi: HP Vectra VE 5| Skärm: HP Ergo 1024| HDD: Toshiba 2033 MB | OS: Windows 95 B | Mus: HP |

Trädvy Permalänk
Forumledare
Registrerad
Okt 2002

Vill man se på aspekter som dyker upp av att skriva ett OS i (mestadels) C++ kan man titta på Haiku: den "moraliska uppföljaren" till BeOS. Merparten av Haikus kärna är C++, liksom dess API.

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011
Skrivet av heretic16:

Så anledningen varför man skriver kärnor i C än i C++ är för att C är "oförrändrat" och därmed är kompilatorn anpassad för CPU:n?

Varför inte skapa en kompilator i C++ som är anpassad för att skriva kärnor? Jag vet att det är mer jobb att skapa en C++ kompilator för en viss CPU än i C. Men när man väl har skapat den så är den klar. Man uppfinner inte hjulet på nytt.

Skickades från m.sweclockers.com

Man kan vända på det: varför skulle man skapa ett nytt språk (är extremt få nya språk som någonsin får någon signifikant andel) från C++ i stället för att köra med C? Att köra med en delmängd av ett existerande språk är i princip alltid en dålig idé, definitivt i modern C++ då mycket av det som idag definierar "bra modern C++" är saker som kanske inte är ett jättebra att använda i ett OS.

@phz gav ett konkret exempel på ett OS som faktiskt är skrivet i C++, tittar man lite snabbt i källkoden för kärnan så ser man t.ex. att undantag inte är tillåtet. Direkt har man då inför restriktioner som normala C++ programmerare inte skulle använda, användning av new kräver detta format

type *ptr = new(std::nothrow) type;

Just i fallet Haiku finns det ändå en poäng med att använda C++, det är en s.k. mikrokärna så de flesta systemfunktioner som typiskt ligger i kärnan i OS som Linux och Windows ligger i "vanliga" applikationer i Haiku (både Windows och Linux är idag hybridkärnor, går att köra systemtjänster i "vanliga" program och det görs också i vissa fall). Det som inte ligger i kärnan kan använda "vanlig" C++, men det som ligger i kärnan kör mer "C with classes" än "riktig" C++. Personligen har jag svårt att se hur det kan vara bättre att försöka förklara för alla vilken delmängd av C++ som faktiskt är tillåtet än bara säga: kör standard C. I många embedded OS kan man faktiskt även använda hela standardbiblioteket i C även i kärnan, så det är verkligen C och ingen godtycklig delmängd. I Linux kan man använda hela språket C, men standardbiblioteket är inte tillgängligt i kärnan.

En annan stor orsak att använda C i kärnor är felsökning. När något går fel i "vanliga" program finns en rad program för att analysera felet, något som är möjligt då det endast är programmet som havererat medan resten av systemet är fullt fungerande. När något går fel i kärnan är det inte alls osannolikt att datorn hänger sig eller att väldigt skumma saker börja hända. C är i stort sett portabel assembler, det är inte superkomplicerat att från en assembler + minnesdump återskapa tillståndet man hade i C-koden när det gick fel. Att för hand göra samma sak i modern C++ (eller något annat modernt språk med mycket finesser) är mer eller mindre hopplöst.

Så ur en mer filosofisk synpunkt är C betydligt närmare HW än C++ då det har en hyfsat enkel koppling till maskinkod (är inte en helt trivial koppling då moderna kompilatorer gör en hel del optimeringar som inte är självklara för en människa).

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

Trädvy Permalänk
Medlem
Plats
Örnsköldsvik
Registrerad
Jun 2008

Så hur ska vi sammanfatta detta nu?

C är alltså mer lämplig att använda än C++ när det kommer till hårdvaran för att:
1. Enklare att porta C kod till maskinkod än C++ kod till maskinkod?
2. Enklare att felsöka C-kod än C++ kod
3. Något mer?

| CPU: MMX 200 MHz Intel Pentium I| GPU: Voodo2 3dfx 8 Mb| RAM: SDRAM 32 Mb 133 Mhz | PSU: 3V fläkt 2W | Chassi: HP Vectra VE 5| Skärm: HP Ergo 1024| HDD: Toshiba 2033 MB | OS: Windows 95 B | Mus: HP |

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011

@heretic16: du fick det bakvänt.

Ofta när man felsöka krascher i kärnan så har man inte mycket mer än en register dump (vilket inkluderar programpekare) och med lite tur har man även en minnesdump. Att med den informationen reda ut vilken kernel-kod det faktiskt motsvarar är betydligt enklare om kärnan är skriven i C än i språk som tillåter mer avancerade konstruktioner.

Sedan är den stora fördelen med C att språket innehåller inga konstruktioner/finesser som inte kan användas i en OS-kärnan, man slipper därför definiera en "tillåten" delmängd av språket. Är ju mycket enklare att säga åt någon: du ska skriva ISO C99 än försöka beskriva, vi använder C++11, fast du får inte använda undantag och om du vill exportera en funktion så får du inte använda polymorfa funktioner då externa funktioner måste ha "C-länkning" eftersom "name mangling" inte är standardiserad...

Sedan finns ju fall när delmängden är självklar, ta Arduino. Där används en delmängd av C++, men vilken delmängd är väldigt enkel att förklara: den som faktiskt går att kompilera med Arduino tool-chain. Finns andra mikrokontrollers som också kör C++ med samma typ av definition av vilken C++. Skulle ändå säga att det är lite problematiskt då en person som är en fena på C++ ändå kommer behöva anpassa sig till denna delmängd.

Och för att förtydliga: rent tekniskt kan man göra allt med C++ som man kan göra med C, så ur den aspekten är de exakt lika nära HW.

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

Trädvy Permalänk
Medlem
Plats
Örnsköldsvik
Registrerad
Jun 2008

Okej. C och C++ är lika nära HW, men C är enklare att sätta upp en kompilator för ett visst chip?

Eller kan man säga: OOP och Templates behövs inte vid hårdvaruprogrammering.

?
Eller så väljs C för att det är portabelt jämfört med C++?

| CPU: MMX 200 MHz Intel Pentium I| GPU: Voodo2 3dfx 8 Mb| RAM: SDRAM 32 Mb 133 Mhz | PSU: 3V fläkt 2W | Chassi: HP Vectra VE 5| Skärm: HP Ergo 1024| HDD: Toshiba 2033 MB | OS: Windows 95 B | Mus: HP |

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008
Skrivet av heretic16:

Okej. C och C++ är lika nära HW, men C är enklare att sätta upp en kompilator för ett visst chip?

C++ innehåller allt som C gör och allt du kan göra i C kan du även göra i C++.

Det är jobbigare att skriva en C++-kompilator än en C-kompilator, men det är ett problem för kompilatortillverkaren, inte för dig. Att använda C++-kompilatorn är inte jobbigare än att använda C-kompilatorn.

Vill du skriva OS-kod, exempelvis drivrutiner, får du stänga av exceptions och en del andra saker. Du kommer inte kunna använda allt i standardbiblioteken, men det gäller även om du skriver motsvarande kod i C. Om du skriver koden i OSet som sköter minnesallokering i användarprocesser (den koden som skall returnera minne till malloc), så kan du inte använda malloc för att allokera minne.

Skrivet av heretic16:

Eller kan man säga: OOP och Templates behövs inte vid hårdvaruprogrammering. ?

Här drar du resonemanget för långt. OOP är en programmeringsmetodik som används flitigt i OS. Dock sker det ofta i form av funktionspekare i strukturerna istället för virtuella funktioner. En sorts fattigmans OOP i C.

Skrivet av heretic16:

Eller så väljs C för att det är portabelt jämfört med C++?

Det har nämnts en del anledningar tidigare i tråden. När C++ var ett "nytt" språk var portabilitet ett problem. Det som gick att kompilera med en kompilator gick inte nödvändigtvis att kompilera med en annan kompilator. Visst kan man stöta på ett och annat problem än i dag, men det beror oftast på förvirring mellan C++98/11/14 och att det läckt saker mellan de olika språkversionerna. C++ som språk har mognat så jag skulle inte säga att C-kod är mer portabel än C++-kod i den meningen att det går flytta koden till olika arkitekturer och den går att kompilera med den kompilatorn som finns tillgänglig för den andra arkitekturen. Däremot är det inte säkert att det finns C++-kompilatorer för alla arkitekturer där det finns C-kompilatorer och det är ett problem för OS-tillverkare.

Trädvy Permalänk
Medlem
Plats
Borås
Registrerad
Okt 2002

Aurdino är ett exempel på hårdvarunära programmering. Jag har för mig att utvecklingsmiljön till Aurdino använder ett programspråk baserat på C++ (en del säger att det ÄR C++, kanske har de rätt). Men jag tror ändå det finns vissa begränsningar på vad man kan göra eller åtminstone riktlinjer för hur man ska programmera. Tror att det blir ganska likt vanlig C i slutändan. Men Aurdino använder en särskild bootloader i botten och jag misstänker denna är skriven i C.

Själv har jag testat att programmerat AVR mikrokontroller direkt i C, samma hårdvara som Aurdino men utan någon särskild bootloader. Så båda programspråken är möjliga för sådan hårdvarunära programmering. Men C verkar komma närmare hårdvaran trots allt.

Bara som ett praktiskt exempel menar jag.

Trädvy Permalänk
Medlem
Registrerad
Maj 2006

C++ innehåller en del väsentliga bitar som ligger på en högre abstraktionsnivå, framförallt relaterat till objektorientering. Man kommer undan med en del grejer man måste skriva en del extrakod för i C, som då blir mer lågnivå.

Däremot måste inte C++kod vara på högre nivå än C. Det som ligger allra närmast hårdvaran, i sammanhanget, är assembler. C/C++ ger programmeraren möjlighet att skriva ganska mycket kod i det också.

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008
Skrivet av ronnylov:

Aurdino är ett exempel på hårdvarunära programmering. Jag har för mig att utvecklingsmiljön till Aurdino använder ett programspråk baserat på C++ (en del säger att det ÄR C++, kanske har de rätt). Men jag tror ändå det finns vissa begränsningar på vad man kan göra eller åtminstone riktlinjer för hur man ska programmera. Tror att det blir ganska likt vanlig C i slutändan. Men Aurdino använder en särskild bootloader i botten och jag misstänker denna är skriven i C.

Arduino är en delmängd av C++. Om du kikar på språkreferenssidan kommer du känna igen allt där från C++. Dock saknas saker som kan ställa till det vid hårdvarunära programmering (exempelvis templates och exceptions som nämnts tidigare i tråden) och man har inte tillgång till C++ standardbibliotek (som använder både exceptions och templates) utan får nöja sig med Arduino-biblioteken (som funkar alldeles utmärks för det du nu behöver göra som Arduino-programmerare.)

Skrivet av ronnylov:

Själv har jag testat att programmerat AVR mikrokontroller direkt i C, samma hårdvara som Aurdino men utan någon särskild bootloader. Så båda programspråken är möjliga för sådan hårdvarunära programmering. Men C verkar komma närmare hårdvaran trots allt.

I Arduino har de gjort livet enklare för dig som programmerare och det enda du behöver göra är att skriva funktionerna setup() och loop(). Sedan sköter de uppsättning av kortet, ser till att anropa setup() innan de startar huvudloopen, som om och om igen anropar loop(). Det är klart att det sker en del bakom kulisserna, men jag ser inte riktigt varför det skulle göra att "C verkar komma närmare hårdvaran". Vad menar du när du påstår det?

Trädvy Permalänk
Medlem
Plats
Borås
Registrerad
Okt 2002
Skrivet av Ingetledigtnamn:

Arduino är en delmängd av C++. Om du kikar på språkreferenssidan kommer du känna igen allt där från C++. Dock saknas saker som kan ställa till det vid hårdvarunära programmering (exempelvis templates och exceptions som nämnts tidigare i tråden) och man har inte tillgång till C++ standardbibliotek (som använder både exceptions och templates) utan får nöja sig med Arduino-biblioteken (som funkar alldeles utmärks för det du nu behöver göra som Arduino-programmerare.)

I Arduino har de gjort livet enklare för dig som programmerare och det enda du behöver göra är att skriva funktionerna setup() och loop(). Sedan sköter de uppsättning av kortet, ser till att anropa setup() innan de startar huvudloopen, som om och om igen anropar loop(). Det är klart att det sker en del bakom kulisserna, men jag ser inte riktigt varför det skulle göra att "C verkar komma närmare hårdvaran". Vad menar du när du påstår det?

Det är väl just det där att om man inte har tillgång till Arduino-biblioteken tvingas man implementera allting själv genom att läsa datablad och liknande och då blir det mer hårdvarunära för programmeraren. Det var mest så jag tänkte. Fast vill man kan man väl göra egna funktioner även med Arduino C++ och man kan använda libraries även i C så skillnaden är väl inte så stor. Hur som helst så är Arduino ett exempel på att man kan använda C++ för riktigt hårdvarunära programmering.

Går man sedan upp till ARM-baserade mikrocontrollers så blir väl stödet för C++ ännu bättre. Men man behöver väl ändå tänka på hur man gör effektiva program. Läste denna artikel för ett tag sedan (men erkänner att jag inte fattar så mycket):
http://www.embedded.com/design/programming-languages-and-tool...-

Trädvy Permalänk
Medlem
Registrerad
Aug 2013
Skrivet av lassep1l1s:

Storleken på programkod (exefiler + bibliotek) mellan C och C++ kan variera kraftigt. Att ett C++ program är 100% större (kräver mer minne) är inte ovanligt då det länkar in klassbibliotek och kräver dll:er. Exekveringen är normalt långsammare i C++ än i C pga. att koden måste passera klassbiblioteken. En försämring av exekveringstid på 50% är inte ovanlig. Det gamla MFC var hopplöst men modernare .NET är bättre. Har portat om C++ till C pga. prestandaproblem.

Nej nej nej nej. Om du ska jämföra två språk och vill bli tagen på allvar så kan det vara en fördel att:

  • Jämföra samma saker.

  • Veta vad du talar om.

Till att börja med finns det inget som heter "klassbibliotek", men jag antar att du syftar på ett helt vanligt bibliotek. Ett bibliotek har nämligen inget koncept av klasser efter att det kompilerats. Det är ett konstrukt för oss programmerare.

Koden "passerar" inte standardbiblioteket om du inte explicit säger åt den att göra det. Du kan exempelvis implementera en container själv, precis som du kunde göra i C. Oavsett så var i många fall standardbiblioteken skrivna av människor med avsesvärt mycket mer erfarenhet än både dig och mig, och därför presterar dessa bättre ändå.

Att "länka in" (?) ett bibliotek är inget som gör en binärfil större och då särskilt inte om det är en .dll fil. Du kanske tänker på att statiskt länka in ett bibliotek? Det är inte heller något man måste göra, och något du kan replikera i C om du vill.

Trädvy Permalänk
Medlem
Registrerad
Feb 2013

Beror på

@heretic16:

Eftersom du troligtvis använder c i inbyggda system. Du kommer inte närmare hårdvaran rent tekniskt i c.