Unterschied c c++ c#



  • loks schrieb:

    Typischerweise haben C-Programmierer, die nichts von C++ wissen wollen, schon mal Bekanntschaft damit gemacht weil sie OOP nicht verstehen.

    Wie ist das? Die machen Bekanntschaft mit C++, weil sie OOP nicht verstehen? Das beleuchtet die Psyche der militanten C++'ler ein wenig. 🙂

    Aber wahrscheinlich darf man nicht zu viel von einer Sprache erwarten, die nicht einmal die Gamma-Funktion über den reellen Zahlen kennt. (oder doch?)



  • TrollEyes schrieb:

    Wahrscheinlich. Und wahrscheinlich ist es in C++ um einiges leichter, Programme zuschreiben, die Anwender nerven, wo andere Entwickler nicht durchblicken und die der Programmierer selbst nach einiger Zeit nicht mehr versteht.

    C++ Programme können ebenso verständlich sein wie Programme in anderen Sprachen, und genauso kryptisch, wie dies auch in jeder Sprache möglich ist (Es kommt auf den Programmierstil an).

    TrollEyes schrieb:

    ...denn ich wäre sehr interessiert, wie man mit 'heavy use of inheritance and templates' Code hinbekommt, der 'typically smaller and faster' als ein äquivalenter C-Code ist. Zumindest Ersteres halte ich für eine schlichte Lüge.

    Ob typischerweise weiß ich nicht, aber es ist definitiv möglich. Alleine schon dadurch das bei Templates nur der Code generiert wird der tatsächlich verwendet wird, Klassen ggf. weggestrichen werden (Die zur Steuerung bestimmter Sachverhalte dienen, die man zur Compilezeit auswerden kann) und der Tatsache das man auf Typen zugeschnittene Konstrukte leicht umsetzen kann, ohne das Konvertierungen nötig werden. Bei letzteren werden auch mal eben viele Sprünge und switches die unter C für die gleiche Arbeit nötig wären einfach mal gestrichen.

    Und davon abgesehen gibt es auch zwei Formen der Vererbung unter C++: Über virtuell oder über Templatetechniken (statische Vererbung vs. dynamischer Vererbung). Und mit letzteren kann man häufig arbeiten, wenn die Unterscheidung nicht erst zur Laufzeit möglich ist (Sondern sich zur Compilezeit auswerten lässt).

    Ich habe die Links damals nicht gesammelt, aber es gab ein paar sehr schöne Beispiele im Netz.

    TrollEyes schrieb:

    Sebastian Pizer schrieb:

    Und das trifft auf C-Programmierer und "deren" Sprache nicht zu?

    Typischerweise haben C-Programmierer, die nichts von C++ wissen wollen, schon mal Bekanntschaft damit gemacht.

    Ich kenne kaum einen C-Programmierer der C++ wirklich mal verstanden hat (ebenso wenig wie was mit Templates überhaupt möglich ist, oder wie man OO wirklich anwendet). Auch ich tat mich damals mit C++ sehr schwer (wenn ich auch nicht von C sondern einigen anderen prozeduralen Sprachen kam), und hinter den wirklichen Sinn von OO und Templates kam erst nach vielen Jahren, und langen Lernen.

    Ich kenne viele die C++ verteufeln, aber wenn du deren C++ Code siehst, verstehst du als C++ Programmierer auch warum. Wer C++ im wesentlichen wie C programmiert, hat C++ nicht verstanden, und hat häufig auch garnicht die Bereitschaft dazu.



  • asc schrieb:

    TrollEyes schrieb:

    Sebastian Pizer schrieb:

    Und das trifft auf C-Programmierer und "deren" Sprache nicht zu?

    Typischerweise haben C-Programmierer, die nichts von C++ wissen wollen, schon mal Bekanntschaft damit gemacht.

    Ich kenne kaum einen C-Programmierer der C++ wirklich mal verstanden hat (ebenso wenig wie was mit Templates überhaupt möglich ist, oder wie man OO wirklich anwendet).

    Ich kann mir auch nicht vorstellen, dass die meisten von den C Programmierern, die C++ ablehnen, überhaupt verstanden haben, was die Spracherweiterungen leisten und wie sie effizient kombiniert und benutzt werden können.

    Als Gegenbeispiel zu Deinem zweiten Teil kann man sich mal den Quellcode des Linux Kernels runter ziehen. Ich würde nicht behaupten, dass OO dort nicht verstanden worden ist. Ich finde es aber schon sehr putzig, wie sie "C++ Features emulieren". Ich habe mir von dem Quellcode bisher nicht viel angesehen, nur mal ein bisschen in die Doku geschaut (zB kobject.txt und kref.txt) und da fällt mir folgendes auf:

    • Emulation von Vererbung durch Einbetten eines "Basis-Structs" in einem "Derived-Struct" und ein relativ "hackiges" Zeiger-Konvertierungs-Makro, welches solche Dinge wie ((Derived*)0)->basis_subobjekt_member) enthält.
    • kobjects haben einen Referenzzähler und einen Zeiger auf einen Typ-Descriptor, welcher sogar einen Zeiger auf eine "release"-Funktion enthält. --> shared_ptr, RTTI, virtual Destructor

    mit dem Unterschied das es nicht Typ-sicher ist und leichter falsch benutzt werden kann:

    • Man muss manuell Referenzzähler über Hilfsfunktionen verändern, was fehleranfällig ist.
    • Beim Aufrufen der Makros muss der übergebene Typ stimmen oder sonst explodiert das ganze "GeCaste" zur Laufzeit.

    Man findet oft Kommentare a la "Böse! Nicht das und das machen! Lieber so und so!" und einiges davon wäre in einem guten C++ Design durch die besseren Abstraktionsmittel überflüssig. Beispiel:

    Der Referenzzähler soll erhöht werden BEVOR man den Zeiger an eine andere Funktion übergibt -- und ja nicht vergessen! -- ausser man interessiert sich danach nicht mehr für das objekt. Also, folgendes

    kref_get(&obj->ref); // Erhöhen des Referenzzählers
      einer_funktion_uebergeben(obj);
      kref_put(&obj->ref); // ich interessiere mich jetzt nicht
                           // mehr dafür, obj darf ich jetzt
                           // nicht mehr benutzen.
    

    darf als Optimierung durch

    // Referenzzähler muss nicht angepasst werden
      einer_funktion_uebergeben(obj);
      // weil wir uns ein kref_put sparen.
      // *obj nicht mehr anfassen ab jetzt !!
    

    ersetzt werden. Schön! Das gleiche bekomme ich mit

    meine_cpp_funktion(mein_shared_zeiger);
       // kann den zeiger noch verwenden
    
    oder:
    
       meine_cpp_funktion(move(mein_shared_zeiger));
       // explizites move() signalisiert: ich sollte
       // den zeiger jetzt nicht mehr lesend benutzen
    

    auch hin -- sogar ohne, dass ich da viel falsch machen kann. Neee, sorry, also wenn das da in C nicht low-level Frickelei ist, ...

    Ich muss mich echt zügeln, nicht über C Programmierer her zu ziehen, die das verzapft haben und dann auch noch C++ bashen ... mann mann mann ... nicht, dass der C Code mies wäre -- es geht ja leider nicht besser -- in C. :p

    Deren verkette Liste habe ich mir auch angeguckt. Ist im Prinzip das gleiche wie boost::intrusive::list, nur ohne Typ-Sicherheit -- mal ganz davon abgesehen, dass structs in C kein member access control haben.

    asc schrieb:

    Auch ich tat mich damals mit C++ sehr schwer (wenn ich auch nicht von C sondern einigen anderen prozeduralen Sprachen kam), und hinter den wirklichen Sinn von OO und Templates kam erst nach vielen Jahren, und langen Lernen.

    Ich kenne viele die C++ verteufeln, aber wenn du deren C++ Code siehst, verstehst du als C++ Programmierer auch warum. Wer C++ im wesentlichen wie C programmiert, hat C++ nicht verstanden, und hat häufig auch garnicht die Bereitschaft dazu.

    👍



  • ...was hab ich nur ausgelöst 😮

    Ich muß mich wohl mit dem Gedanken anfreunden, dass es bei der Wahl der richtigen
    Programmiersprache kein richtig oder falsch gibt.

    Da plattformunabhängig liebäugle ich mittlerweile mit Java.

    Fazit: Die Wahl der richtigen Sprache ist so unproblematisch wie ein Fahrzeug.
    Problematisch sind nur Lenker, die Fahrgäste und die Straße 🤡


  • Administrator

    truecolor schrieb:

    ...was hab ich nur ausgelöst 😮

    Tja, deswegen hatte Mr. N diesen Satz in seinem Beitrag stehen:

    Mr. N schrieb:

    (Ich tue einfach mal so, als würde ich nicht vermuten, dass das ein Troll-Thread ist.)

    😉

    truecolor schrieb:

    Ich muß mich wohl mit dem Gedanken anfreunden, dass es bei der Wahl der richtigen Programmiersprache kein richtig oder falsch gibt.

    Doch gibt es schon, aber es gibt nicht DIE Programmiersprache. Es gibt nur eine Aufgabe und dafür geeignete Programmiersprachen (Mehrzahl) 😉

    truecolor schrieb:

    Da plattformunabhängig liebäugle ich mittlerweile mit Java.

    *sein Maul öffnet, um was zu sagen, es aber wieder schliesst*
    Ne, sonst geht das ewig so weiter 😃

    Grüssli



  • TrollEyes schrieb:

    Das müsste er wohl tun, denn ich wäre sehr interessiert, wie man mit 'heavy use of inheritance and templates' Code hinbekommt, der 'typically smaller and faster' als ein äquivalenter C-Code ist. Zumindest Ersteres halte ich für eine schlichte Lüge.

    ein virtual aufruf ist schneller als ein aufruf über einen funktionszeiger.

    und
    o.f() ist standardmäßig schneller als f(o)
    😉

    idR sind nachgebaute Sachen wie vererbung oder virtuelle Funktionen in C langsamer als in C++.



  • loks schrieb:

    TrollEyes schrieb:

    Typischerweise haben C-Programmierer, die nichts von C++ wissen wollen, schon mal Bekanntschaft damit gemacht.

    Ja, so einen kenne ich sogar beruflich. Jedoch fehlt da ein Teilsatz:
    Typischerweise haben C-Programmierer, die nichts von C++ wissen wollen, schon mal Bekanntschaft damit gemacht weil sie OOP nicht verstehen.

    Solche mag es geben, aber es gibt auch welche, die zusätzlich zu C andere Sprachen mit OOP verwenden. Ich glaube nicht, dass es nur am Nichtverstehen von OOP liegt.

    asc schrieb:

    Ich kenne kaum einen C-Programmierer der C++ wirklich mal verstanden hat (ebenso wenig wie was mit Templates überhaupt möglich ist, oder wie man OO wirklich anwendet). Auch ich tat mich damals mit C++ sehr schwer (wenn ich auch nicht von C sondern einigen anderen prozeduralen Sprachen kam), und hinter den wirklichen Sinn von OO und Templates kam erst nach vielen Jahren, und langen Lernen.

    Hattest Du mal Gelegenheit dazu, andere OOP-Sprachen wie z.B. C# mit C++ zu vergleichen? Und wenn ja, was ge- oder missfällt dir an ihnen?

    Sebastian Pizer schrieb:

    Als Gegenbeispiel zu Deinem zweiten Teil kann man sich mal den Quellcode des Linux Kernels runter ziehen. Ich würde nicht behaupten, dass OO dort nicht verstanden worden ist. Ich finde es aber schon sehr putzig, wie sie "C++ Features emulieren".

    Als C++ Emulation würde ich es nicht bezeichnen. Sie verwenden bewährte Techniken, die auch in C++ möglich sind. Das Thema "Referenzzählung" gilt allgemein und muss in jeder Sprache, mit den verfügbaren Möglichkeiten, anders implementiert werden.

    Sebastian Pizer schrieb:

    Man findet oft Kommentare a la "Böse! Nicht das und das machen! Lieber so und so!" und einiges davon wäre in einem guten C++ Design durch die besseren Abstraktionsmittel überflüssig.

    Du weisst selbst, wie viele Fallstricke C++ schon von sich aus beinhaltet. Bevor jemand so sicher im Umgang mit C++ ist, dass er ein Gespür für die vielen "Böses" der Sprache entwickelt hat, haben andere schon einen Betriebssytem-Kernel in C programmiert.

    Sebastian Pizer schrieb:

    Ich muss mich echt zügeln, nicht über C Programmierer her zu ziehen, die das verzapft haben und dann auch noch C++ bashen ... mann mann mann ... nicht, dass der C Code mies wäre -- es geht ja leider nicht besser -- in C.

    Mach das, wenn Dir danach ist. Es wird nichts daran ändern, dass der Linux-Kernel ein sehr brauchbares und äußerst stabiles Stück Software ist. Jeder setzt andere Prioritäten. Die einen wollen eine Sprache mit 1000 Tricks und Tücken, die mehr Selbstzweck, hauptsache schön, voller Typsicherheit und Automatismen. Andere wiederum wollen schörkellose Software schreiben, die einfach nur funktionieren soll.

    Shade Of Mine schrieb:

    TrollEyes schrieb:

    Das müsste er wohl tun, denn ich wäre sehr interessiert, wie man mit 'heavy use of inheritance and templates' Code hinbekommt, der 'typically smaller and faster' als ein äquivalenter C-Code ist. Zumindest Ersteres halte ich für eine schlichte Lüge.

    ein virtual aufruf ist schneller als ein aufruf über einen funktionszeiger.

    Ich meinte den ersten Teil der Aussage. Normalerweise macht Verwendung von Templates und Vererbung den Code grösser.



  • TrollEyes schrieb:

    Ich meinte den ersten Teil der Aussage. Normalerweise macht Verwendung von Templates und Vererbung den Code grösser.

    Nein. Sie machen den Code kleiner. Meistens sogar den generierten asm code 😉

    typedef struct {
      int a;
    } Base;
    
    typedef struct {
      Base* p;
      int b;
    } Derived;
    
    //versus
    
    class Base {
      int a;
    };
    
    class Derived : public Base {
      int b;
    };
    

    wow, riesen unterschied.
    wenn du vererbung hast, musst du sie ja in c auch irgendwie nachbilden...

    und templates sparen sowieso massig.



  • TrollEyes schrieb:

    Sebastian Pizer schrieb:

    Als Gegenbeispiel zu Deinem zweiten Teil kann man sich mal den Quellcode des Linux Kernels runter ziehen. Ich würde nicht behaupten, dass OO dort nicht verstanden worden ist. Ich finde es aber schon sehr putzig, wie sie "C++ Features emulieren".

    Als C++ Emulation würde ich es nicht bezeichnen.

    Nenne es wie Du willst. Ich erkenne darin das, was Destruktoren, RTTI, virtuelle Funktionen und Vererbung ausmacht, Dinge die von "Euch" verteufelt werden, aber im Vergleich zu dem, was da im Linuxkernel gemacht wird, fast das gleiche ist. Die C++ Version kommt dafür ohne Reinterpretierungs-Casts, Makros und Zeigerarithemtik-Hacks aus, bietet besseres Compile-Time-Checking durch Compilerunterstützung, einiges an Automatisierungsmöglichkeiten und verbesserte Kapselung zur Reduktion von Fehlern (zB RAII für Referenzzähler) und sogar noch einen Performanz-Plus an (Generizität + Inlining).

    TrollEyes schrieb:

    Sebastian Pizer schrieb:

    Man findet oft Kommentare a la "Böse! Nicht das und das machen! Lieber so und so!" und einiges davon wäre in einem guten C++ Design durch die besseren Abstraktionsmittel überflüssig.

    Du weisst selbst, wie viele Fallstricke C++ schon von sich aus beinhaltet.

    Ja, ich weiß, dass es viele Anfänger gibt, die von Tuten und Blasen keinen Plan haben. Und? Ich würde auch keinen Anfänger an den Linuxkernel setzen. Aber selbst ein Profi vergisst vielleicht mal ein kref_put(&obj->ref_counter); (siehe Kernel) und erhält dadurch ein Speicherleck. Der Unterschied: In der C++ Version muss ich nur bei der Implementierung des schlauen Zeigers aufpassen. In der C Version muss ich überall dort aufpassen, wo ich Referenzzählung benutze (schlechtere Kapselung).

    TrollEyes schrieb:

    Bevor jemand so sicher im Umgang mit C++ ist, dass er ein Gespür für die vielen "Böses" der Sprache entwickelt hat, haben andere schon einen Betriebssytem-Kernel in C programmiert.

    Was ist das denn für ein bescheuerter Vergleich? Als ob C++ lernen und richtig anwenden schwieriger ist, als sich in C einen Linuxkernel-artigen Programmierstil zu erarbeiten (darf man nicht unterschätzen, wie viel Programmiererfahrung da beteiligt ist). Als Anfänger baut man in C doch auch nur Scheiße.

    Wenn man nicht auf'n Kopf gefallen ist, schafft man C++ auf Experten-Niveau in 2 Jahren -- entsprechende Motivation vorausgesetzt. Und wenn das auch mit vollem Interesse und super Motivation nach 2 Jahren nicht "geklappt hat", will ich von demjenigen auch keine in C geschriebene Software sehen; denn dann wäre derjenige höchstwahrscheinlich einfach nur inkompenent.

    TrollEyes schrieb:

    Sebastian Pizer schrieb:

    Ich muss mich echt zügeln, nicht über C Programmierer her zu ziehen, die das verzapft haben und dann auch noch C++ bashen ... mann mann mann ... nicht, dass der C Code mies wäre -- es geht ja leider nicht besser -- in C.

    Mach das, wenn Dir danach ist. Es wird nichts daran ändern, dass der Linux-Kernel ein sehr brauchbares und äußerst stabiles Stück Software ist.

    Habe ich das bestritten? Ist das so eine Art Rechtfertigung fehlender Abstraktionsmittel? A la "Es geht ja auch ohne!"?

    TrollEyes schrieb:

    Jeder setzt andere Prioritäten. Die einen wollen eine Sprache mit 1000 Tricks und Tücken, die mehr Selbstzweck, hauptsache schön, voller Typsicherheit und Automatismen. Andere wiederum wollen schörkellose Software schreiben, die einfach nur funktionieren soll.

    Die einen wollen Compiler-Unterstützung für Abstraktionen, die anderen basteln sich das mehr oder weniger schlechter nach. So sieht's doch aus!

    TrollEyes schrieb:

    Ich meinte den ersten Teil der Aussage. Normalerweise macht Verwendung von Templates und Vererbung den Code grösser.

    Im Vergleich zu was? 🙄 Irgendwelche Design-Alternativen musst Du dazu im Kopf für C haben. Übrigens: So eine Design-Alternative wäre dann auch in C++ möglich! :p Keiner zwingt Dich, Sprachmittel zu missbrauchen.



  • TrollEyes schrieb:

    asc schrieb:

    Ich kenne kaum einen C-Programmierer der C++ wirklich mal verstanden hat (ebenso wenig wie was mit Templates überhaupt möglich ist, oder wie man OO wirklich anwendet). Auch ich tat mich damals mit C++ sehr schwer (wenn ich auch nicht von C sondern einigen anderen prozeduralen Sprachen kam), und hinter den wirklichen Sinn von OO und Templates kam erst nach vielen Jahren, und langen Lernen.

    Hattest Du mal Gelegenheit dazu, andere OOP-Sprachen wie z.B. C# mit C++ zu vergleichen? Und wenn ja, was ge- oder missfällt dir an ihnen?

    Reicht es wenn ich neben C++ auch schon mit Java gearbeitet und mit C# privat programmiere? Und neben den Vor- und Nachteilen zu den Sprachen muss ich sagen, das jede etwas anders programmiert wird.

    Aber wenn du unbedingt einen Vergleich haben willst (Ich nehme C# als Vergleich, da ich zwar Javakenntnisse habe, diese aber schon etwas zurück liegen), natürlich nur Auszugsweise:

    1. Templates (Vorteil C++)
    Die Templates unter C++ geben ein deutlich mächtigeres Werkzeug als Generics mit, so kann man z.B. mittels Templates sicherstellen das es z.B. eine Standardumsetzung für die Sortierung von Containern gibt, aber im Falle der Container, in dem eine bessere Möglichkeit vorliegt, diese verwendet wird (Dies ist nur ein sehr einfaches Beispiel).

    2. Wert-/Referenzübergaben sowie const (Vorteil C++)
    Unter C++ kann man bei Funktionsparametern eindeutig sehen ob es eine Referenz oder eine Werteübergabe ist, und man kann auch steuern/anzeigen ob sie Änderungen vornehmen oder nicht. Unter C# muss man dann immer wieder zwischen Werte- und Referenztypen unterscheiden, und sieht nicht, ob ein Wert von einer Funktion möglicherweise modifiziert wird.

    3. Umfangreiches einheitliches Framework (Vorteil C#)
    Bei C# kann man relativ sicher sein, das man mit dem Lernen des .Net Frameworkes nicht viel falsch machen kann. Unter C++ hat man diverse Grafikbibliotheken, Frameworks etc. und muss mit hoher Wahrscheinlichkeit mit jeder neuen Firma sich erst wieder an neue Bibliothekten gewöhnen, zumal diese auch inkonsistenter von der Verwendung untereinander sind (Auch wenn das .Net Framework auch Inkonsistenzen bei der Verwendung hat, so ist es "mehr" aus einem Rutsch).

    4. Zeigerproblematiken (Knapper Vorteil von C++)
    Ungefragt, unter C# scheint die Verwendung von Objekten etc. leichter zu sein. Aber jeder Referenztyp unter C# kann gleichwohl Null annehmen, und es fällt leichter in die NULL-Pointer Falle zu stolpern, wenn man die Problematik nicht offensichtlich sieht. Bei C++ denke ich bei jeden Zeiger schon automatisch nach, ob nicht vielleicht doch ein Nullwert kommen kann. Und bei C++ habe ich auch die Auswahl ob ich den Zeiger selbst verwalte oder mittels Smartpointern arbeite, unter C# weiß man nicht wann Objekte gelöscht werden, auch wenn es ungefragt bequemer ist.

    5. Bezahle nur für das was du brauchst & Programmkontrolle (Vorteil von C++)
    In C# ist vieles auf Sicherheit getrimmt - was natürlich auch seine Vorzüge hat. Aber wenn man weiß, was man braucht, kann man in C++ deutlich mehr Kontrolle auf das erstellte Programm nehmen. Ich brauch keine Bereichsprüfungen wenn ich genau weiß wie groß ein Container ist, aber falls doch, habe ich die Auswahl der Mittel.

    6. Dynamische Bibliotheken (Klarer Vorteil C# & .Net)
    Wenn man Bibliotheken leicht erstellen, und gar Sprachübergreifend verwenden kann, ist dies schon ein klarer Vorteil. In C++ fehlt eine standardisierte ABI und es k***t massiv an, wenn man immer von C++ auf C wandeln muss um eine Bibliothek zu verwenden, ohne gleich auch noch an den Compiler und sogar der Compilerversion gebunden zu sein.

    7. Tipaufwand (Klarer Vorteil C# & .Net)
    Wenn es nur darum geht ein Ergebnis X umzusetzen, wird man in der Regel dieses Problem in C# mit weniger Schreibaufwand lösen können. Es gab mal eine (wenn auch nicht ganz aussagekräftige) Statistik wie viele Zeilen Code man in etwa in Verhältnis unter den Sprachen benötigt um das gleiche Ziel zu erreichen. Das merkt man durchaus. Ich behaupte wenn man ein komplexeres Programm einmal mit C++ und einmal mit C# lösen muss, wird in der Regel bei gleichen Kenntnisstand und gleicher Sorgfalt das C#-Team vorne sein.

    8. Einarbeitungszeit (Klarer Vorteil C#)
    Ungefragt ist C# leichter zu lernen, als C++. Vor allen wenn man ins eingemachte der Sprache geht. C++ ist mächtiger, aber halt auch deutlich komplexer.

    9. Performance (Vorteil C++)
    Performance ist nicht alles, aber wenn man mal darauf angewiesen ist, wird man in der Regel mit C++ deutlich besser fahren. Es gibt theoretische Ausnahmen, in der Praxis habe ich aber noch keine C# oder Java Programme erlebt, die bei in etwa gleicher Qualität schneller wären als ein C++ oder C Pendant.

    TrollEyes schrieb:

    Du weisst selbst, wie viele Fallstricke C++ schon von sich aus beinhaltet.

    Das aus dem Mund eines, der C hervorhebt. Ja, C++ ist komplex und hat seine Fallstricke, aber man hat mit C++ auch die Möglichkeit viele Fallstricke von C zu umgehen, und hat gleichzeitig ein noch weiterführende Strukturierungsmöglichkeiten für ein Programm (Was IMHO die Wartbarkeit und Wiederverwertbarkeit erhöht), zumal man viel Komplexität auch gut hinter Schnittstellen verbergen kann (Was mir mit OO-Mitteln bislang leichter gefallen ist, als mit den Mitteln der strukturierten Programmierung).

    Ich behaupte sogar, das wenn man einerseits die C-Spezifischen Teile auslässt, anderseits das Thema Templates nur grundlegend anschneidet (Damit man die STL verwenden kann, und in etwa weiß was möglich ist), man C++ ähnlich schnell lernen kann wie C.

    TrollEyes schrieb:

    Bevor jemand so sicher im Umgang mit C++ ist, dass er ein Gespür für die vielen "Böses" der Sprache entwickelt hat, haben andere schon einen Betriebssytem-Kernel in C programmiert.

    Und schießen mit wilden Zeigern um sich, ignorieren aus versehen auch mal Fehlerrückgaben, Ressourcenfreigaben...

    TrollEyes schrieb:

    Die einen wollen eine Sprache mit 1000 Tricks und Tücken, die mehr Selbstzweck, hauptsache schön, voller Typsicherheit und Automatismen. Andere wiederum wollen schörkellose Software schreiben, die einfach nur funktionieren soll.

    Und scheitern dann aufgrund von deren Problemen. C und C++ nimmt sich wirklich nichts, was in C++ durch die weitere Komplexität an Problemen dazu gekommen ist, macht es auch wieder gut, in dem es viele C-Probleme löst.

    Und um den ganzen noch etwas die Krone aufzusetzen: Ich war einige Zeit in einer Firma in der im Projekt ein C-Entwickler mit deutlich mehr Erfahrung saß als ich in C++ habe. Ja, mir sind C++ spezifische Fehler passiert, die Software instabil gemacht haben aber weitgehend die C-Codeteile, und für letztere war auch der Zeitaufwand für das finden und beseitigen höher. Und dies war nicht das einzige Projekt in dem es so lief - das Gegenbeispiel habe zumindest ich noch nicht in einen Projekt erlebt.

    Oh, ungefragt, kryptische Fehlermeldungen von Templates sind unschön, ebenso ist Exceptionhandling für sich alleine genommen auch nicht der Lösung letzter Schluss. Und auch mit C++ Mitteln habe ich auch schon Access Violation ausgelöst, aber irgendwie waren die Fehler dennoch meist leichter zu finden...

    TrollEyes schrieb:

    Ich meinte den ersten Teil der Aussage. Normalerweise macht Verwendung von Templates und Vererbung den Code grösser.

    Ja und Nein. Templates können Code vergrößern, aber ebenso auch verkleinern. Und häufig bekommt man dank Templates auch einen sicheren und schnelleren Code geliefert.

    Wenn du nur die "klassischen" Templatekonstrukte betrachtest, magst du auch noch recht haben. Wenn man z.B. std::vector mit drei Verschiedenen Typen aufruft, hat man den Code effektiv dreimal im Programm stehen (Wobei gleichzeitig Fehlerquellen und Umwandlungen aufgrund des Typs ausgeschlossen sind). Anderseits wird für ein Template auch nur der Code erzeugt, der konkret verwendet wird (Was bei einigen Templatekonstrukten sogar wichtig wird).

    Hier noch etwas zur Performance, zu einem kleinen Gegenbeispiel des Code Bloat. Grundsätzlich kann man sagen das Templates häufig zu mehr Code führen können, aber es kann ebenso das Gegenteil der Fall sein (Gibt einige Beispiele davon im Netz). Aber ungeachtet dessen: Selbst wenn es den Code etwas aufbläht, ist mir persönlich eine geringere Fehlerquote wichtiger, als die Größe.



  • asc schrieb:

    Selbst wenn es den Code etwas aufbläht, ist mir persönlich eine geringere Fehlerquote wichtiger, als die Größe.

    ebend. Was nutzt Performance wenn es nur bedeutet das das Programm schneller abstürzt. Mein Lieblings-C-Programmierer (sarcasm warnung) hatte da so ne Stelle in Seinem Code die garantiert unter bestimmten (realistisch möglichen) Umständen eintrat. Sein Argument: Das war die schnellste Lösung, daher waren die potentiellen Abstürze akzeptabel...



  • Shade Of Mine schrieb:

    class Base {
      int a;
    };
    
    class Derived : public Base {
      int b;
    };
    
    // versus
    
    typedef struct {
      int a;
    } Base;
    
    typedef struct {
      Base* p;
      int b;
    } Derived;
    

    Am konkreten Beispiel...

    Linux Kernel kobject-Framework (vereinfacht) + Beispiel:

    #include <stdio.h>
    #include <stdlib.h>
    
    /* --------8<--------[ do it yourself abstraction framework in C ]--------8<-------- */
    
    struct kobject;
    
    struct ktype {                         /* runtime type information */
    	int type_id;
    	void (*release)(struct kobject*);  /* acts as virtual destructor */
    };
    
    struct kobject {
    	struct ktype* type_ptr;
    	/* more stuff */
    };
    
    void kobject_init(struct kobject* ob, struct ktype* ty)
    {
    	ob->type_ptr = ty;
    	/* more stuff */
    }
    
    void kobject_release(struct kobject* ob)
    {
    	/* more stuff */
    	ob->type_ptr->release(ob);
    }
    
    /* Masterpiece of a pointer arithmetic hack including
     * a dereference of a null pointer! Congratulations!
     * This is used to convert a pointer "from Base to Derived"
     * (Did I already say it's not type-safe at all?)
     */
    #define CONTAINER_OF(ptr_,type_,member_) \
       ((type_*)((char*)ptr_-((char*)(&((type_*)0)->member_)-((char*)0))))
    
    /* --------8<--------[ User Code ]--------8<-------- */
    
    struct myclass {                      /* my derived class */
    	struct kobject kobj;              /* base subobject */
    	int foo;
    	/* more stuff */
    };
    
    void myclass_release(struct kobject*); /* This is gonna be my "destructor" */
    
    struct ktype myclass_ktype = { /* runtime type information about "myclass" */
    	12345,           /* some type ID */
    	myclass_release  /* pointer to "destructor" */
    };
    
    struct myclass *myclass_create(int parameter)
    {
    	struct myclass *ptr;
    	ptr = (struct myclass*)malloc(sizeof(struct myclass));
    	if (!ptr) return 0;
    	kobject_init(&ptr->kobj, &myclass_ktype);
    	ptr->foo = parameter;
    	return ptr;
    }
    
    void myclass_release(struct kobject *obj)
    {
    	struct myclass *p;
    	p = CONTAINER_OF(obj, struct myclass, kobj);
    	printf("%s\n","This is my destructor!");
    	p->foo = 0;
    	free(p);
    }
    
    /* --------8<-------- */
    
    int main(int argc, char *argv[])
    {
    	struct myclass *myobj;
    	struct kobject *ko;
    	myobj = myclass_create(42);
    	ko = &myobj->kobj;
    	kobject_release(ko);
    	return 0;
    }
    

    Alternativ, wie man es in C++ hätte machen können:

    #include <iostream>
    
    class kobject
    {
    public:
    	virtual ~kobject() = 0;
    	/* more stuff */
    };
    
    kobject::~kobject() {}
    
    // --------8<--------
    
    class myclass : public kobject
    {
    public:
    	explicit myclass(int parameter);
    	~myclass();
    private:
    	int foo;
    };
    
    myclass::myclass(int param)
    : foo(param)
    {}
    
    myclass::~myclass()
    {
    	std::cout << "This is my destructor!\n";
    }
    
    // --------8<--------
    
    int main()
    {
    	myclass* pderiv = new myclass(42);
    	kobject* pko = pderiv;
    	delete pko;
    }
    

    Ich könnte an der C-Version noch einiges anmeckern, spare ich mir aber jetzt. Kann sich jeder selbst überlegen, ob ihm die C Version gefällt.

    Mein Fazit: Da stimmt doch irgendwas nicht, wenn man in C so etwas verzapft und dann C++ Scheiße findet. Ich kann diese Leute echt nicht mehr ernst nehmen. Ich meine, ich versuche echt nicht voreingenommen zu sein. Aber denen fehlt anscheinend jede Basis, um kompetent über C++ zu urteilen.

    Edit: Ha! Ich hatte sogar einen Bug im Pointer-Arithmetik-Makro! Ja, was wär dem Profi natürlich nicht passiert! Ist klar...

    Gruß,
    SP



  • Wo ist der vergleichbare Kernel (von Umfang) in C++?



  • Was meinst Du?



  • Na du pickst aus einem C-Kernel Stellen raus die nicht gefallen, also will ich aus einem im Umfang vergleichbaren C++-Kernel Stellen rauspicken die mir nicht gefallen. Naja, eigentlich wollte ich nur dezent darauf hinweisen, dass der Vergleich hinkt weil es eben keine Vergleichsmöglichkeit gibt.



  • Tim schrieb:

    Na du pickst aus einem C-Kernel Stellen raus die nicht gefallen, also will ich aus einem im Umfang vergleichbaren C++-Kernel Stellen rauspicken die mir nicht gefallen. Naja, eigentlich wollte ich nur dezent darauf hinweisen, dass der Vergleich hinkt weil es eben keine Vergleichsmöglichkeit gibt.

    Ich habe die Stellen nicht rausgesucht, weil ich sie schlecht fand -- zumindest nicht für C Maßstäbe -- sondern weil man dort sehen kann, wie Dinge programmiert wurden, welche der C++ Compiler automatisch und besser hätte generieren können. Ich habe das Beispiel gebracht, weil es meiner Meinung nach den C++ Gegnern, welche so etwas in C schreiben würden, ordentlich den Wind aus den Segeln nimmt, wenn sie über diese C++ Features schimpfen ("langsam", "Speicheroverhead", siehe c++ performance).

    Linus Torvalds schrieb:

    [...] In other words, the only way to do good, efficient, and system-level and
    portable C++ ends up to limit yourself to all the things that are
    basically available in C. And limiting your project to C means that people
    don't screw that up, and also means that you get a lot of programmers that
    do actually understand low-level issues and don't screw things up with any
    idiotic "object model" crap
    . [...]

    LOL! Herrlich! Was ist denn dann kobject ?

    Der Punkt ist: In C hätte man das auch nicht viel besser machen können (sozusagen schon "optimal" in C). Ich kann die Schuld also nicht auf den Programmierer schieben. In C++ schon. In C++ hätte man es besser machen können. Es geht hier (bei mir) um das, was die Sprachen leisten (können). So ist der Vergleich meiner Meinung nach um einiges sinnvoller als zwei völlig verschiedene Kernel zu nehmen und dann da mal drüber zu gucken und "ugly code" zu suchen.

    Wenn Du aus einem vergleichbaren C++ Kernel etwas raus pickst, was Dir nicht gefällt, dann zeig mir aber auch bitte eine C Version, die Dir besser gefällt. Dass Dein "eleganteres C Design" auch in C++ möglich wäre, muss ich hoffentlich nicht erwähnen. Hier kann ich die Schuld also auf den Programmierer schieben. Das ist kein Argument mehr für eine schlechte Programmiersprache.

    ...wundert mich immer wieder, wie man bei so etwas die Stärke von C++ ignorieren kann. Ich sehe hier in der C Version weitaus mehr Fallstricke. Die C++ Version ist schön lesbar. Nein, aber zugeben darf man das nicht. Da muss man ausweichen. "Der Vergleich hinkt". Is klar...

    Gruß,
    SP



  • Sebastian Pizer schrieb:

    In C++ hätte man es besser machen können. Es geht hier (bei mir) um das, was die Sprachen leisten (können).

    Es ist wohl kein Kunststück, wenn man ein Beispiel wählt (hier statisches, C++-ähnliches OOP, Klassen mit Destruktoren), für das die eine Sprache schon von Haus aus gemacht ist, um dann zu zeigen, in welcher Sprache sowas weniger Handarbeit erfordert. Die Frage, ob der Einsatz von C++ anstatt C im Linux-Kernel grundsätzlich einen signifikanten Vorteil hätte, kannst Du so nicht beantworten. Dazu müsste man viele andere Faktoren berücksichtigen, die ich hier aber nicht aufzählen möchte, damit kein Flamewar losbricht. Aber falls es Dich interessiert, was Microsoft zu C++ im Windows-Kernel meint, dann schau dir mal das an.

    Sebastian Pizer schrieb:

    Linus Torvalds schrieb:

    [...] In other words, the only way to do good, efficient, and system-level and
    portable C++ ends up to limit yourself to all the things that are
    basically available in C. And limiting your project to C means that people
    don't screw that up, and also means that you get a lot of programmers that
    do actually understand low-level issues and don't screw things up with any
    idiotic "object model" crap
    . [...]

    LOL! Herrlich! Was ist denn dann kobject ?

    Er befürchtet unter anderem, dass Entwickler sonst C++ OOP an Stellen einsetzen würden, an denen es unnnötig oder sogar nachteilig ist. Im Userland darf man z.B., nach Lust und Laune, einen std::string hier und ein std::vector dort benutzen. Im Kernel aber gilt das nicht mehr.

    Ich finde, du bist einfach viel zu emotional bei der Sache.



  • Sebastian Pizer schrieb:

    ...wundert mich immer wieder, wie man bei so etwas die Stärke von C++ ignorieren kann. Ich sehe hier in der C Version weitaus mehr Fallstricke. Die C++ Version ist schön lesbar. Nein, aber zugeben darf man das nicht. Da muss man ausweichen. "Der Vergleich hinkt". Is klar...

    Wo ignoriere ich hier die Stärke von C++ in diesem Fall? 😕 (edit: Mit "in diesem Fall" meine ich nicht den Kernel)

    Ein anderes Thema: In meinem Code ist so ziemlich jede zweite Variable eine globale Größe. Was sagst du dazu?



  • TrollEyes schrieb:

    Es ist wohl kein Kunststück, wenn man ein Beispiel wählt

    Nun, es basiert auf dem kobject-Design des Linux Kernels und ist nicht etwas, was ich mir komplett selbst ausgedacht habe. In Verbindung mit der "object model crap"-Geschichte finde ich das sehr interessant. 🙂

    TrollEyes schrieb:

    Die Frage, ob der Einsatz von C++ anstatt C im Linux-Kernel grundsätzlich einen signifikanten Vorteil hätte, kannst Du so nicht beantworten.

    Hatte ich auch gar nicht vor. Von mir aus können sie machen, was sie wollen.

    TrollEyes schrieb:

    Ich finde, du bist einfach viel zu emotional bei der Sache.

    🙂

    jepp, mag sein ... muss zugeben, dass der Blick in den Linux Kernel Quellcode meinem Ego gut getan hat. 🙂

    Tim schrieb:

    Wo ignoriere ich hier die Stärke von C++ in diesem Fall?

    Nicht? Sorry. Das kommt irgendwie so rüber, wenn man nur den einen oder anderen Punkt aufgreift und kritisiert. Ich fand das Beispiel sehr erhellend. Ein negativer Kommentar dazu sah nach genereller Ablehnung aus.

    Tim schrieb:

    Ein anderes Thema: In meinem Code ist so ziemlich jede zweite Variable eine globale Größe. Was sagst du dazu?

    Kommt drauf an. Kann ja durchaus Sinn machen. Kann ich so nicht beurteilen. Aber "jede zweite" klingt schon nach ungewöhnlich viel. Es hat aber recht wenig mit der Sprachdiskussion zu tun.

    over and out,
    SP



  • Sebastian Pizer schrieb:

    Ich habe das Beispiel gebracht, weil es meiner Meinung nach den C++ Gegnern, welche so etwas in C schreiben würden, ordentlich den Wind aus den Segeln nimmt, wenn sie über diese C++ Features schimpfen ("langsam", "Speicheroverhead"

    Ich sehe es auch so, dass C gegenüber C++ keine Vorteile hat, aus einem einfachen Grund: man kann in C++ wie in C programmieren. Es besteht kein Zwang zur Verwendung von Klassen, Templates, Vererbung oder der STL. Wo also bestimmte C++ Features nicht angebracht sind, da benutzt man sie einfach nicht und fertig. Benutzer anderer Sprachen, seien es nun C#, Java, Python oder was anderes, könnten vielleicht das eine oder andere an C++ bemängeln, was ihre Sprache besser kann. Aber C-Programmierer können das nicht, weil mit C++ alles (und mehr) möglich ist was in C auch geht. Ich möchte gern ein glaubhaftes Argument hören, warum man C C++ vorziehen sollte. Aber ich glaube, es gibt keins.


Anmelden zum Antworten