Unterschied c c++ c#



  • DEvent schrieb:

    Welche Vorteile würde mir den C++ bringen? Das ich die super STL verwenden kann? Danke, aber auf die ganzen Iteretoren, doppelt und dreifach, kann ich verzichten.

    Man kann vorteile von C++ auch ohne die sogenannte STL geniessen. Ich persönlich mag die standardbibliothek von C++ überhaupt nicht und nutze die auch so gut wie gar nicht.
    Du schreibst da oben ein dutzend zeilen code, und darunter den gleichen code, nur mit klassen. Das ist der einzige unterschied in deinem code. Und wenn das für dich der einzige unterschied zwischen C und C++ ist, dann hast du's wirklich nicht verstanden und solltest dich intensiver mit der materie beschäftigen.

    Allein schon details wie diese hier

    NoiseData data;
        if (!noiseread.read(&data, 1))
    

    sind so typisches "C code in C++ gegossen". Wer C++ so programmiert, zeigt doch schon, dass er's nicht verstanden hat.



  • Bashar schrieb:

    fricky reloaded? Wenn du von Destruktoren und Exceptions noch nichts gehört hast, aber meinst, dich unbedingt zum Thema C vs. C++ äußern zu müssen, ist es an dir, dich (vorher!) über das Thema zu informieren. Stattdessen polterst du hier mit irgendwelchem Unsinn rum und verlangst dann aufgeklärt zu werden.

    Das war klar, dass Exceptions vorgeschlagen werden. Tatsache it aber, Exceptions C++ sind extrem nutzlos, bis auf den kleinen Vorteil, dass man wenigstens so Fehler in Operatoren abfragen kann. Dann kommt noch der ganze bloat nur wenn man Exceptions einschaltet. Z.B. 10 bis 20% in wxWidgets.



  • Tatsache ist das, sagst du. Soso.



  • Und destruktoren? Unterschlägst du?

    Dein C-Code ist btw scheisse... wenn noiseOpen funktioniert, noiseStart aber fehlschlägt, ruft niemand mehr noiseClose auf. Und das ist ja wohl wichtig, sonst würdest du's weiter unten nicht explizit aufrufen.
    Mit einem vernünftigem try-catch-block und einem vernünftig implementierten desktruktor in Noiseread kein problem. Vor allem ohne dass man sich in lauter if-blöcke stürzen müsste.



  • Zu den Destruktoren, du willst sicher die close() Funktion in den Destruktor packen? Was passiert aber, wenn sie Fehlschlägt? Ein Dtor kann keine Exceptions werfen, der Fehler wird für immer unentdeckt bleiben (es sei den ich Log das in eine Datei oder gebe was in der Konsole aus). In dem Fall eben ist das nicht so schlimm weil ich das Programm beende, aber das Gerät bleibt im Fehlerzustand und muss neu gestartet werden.



  • Wie behandelst du denn in deinem C code einen fehler in der close-funktion?



  • MasterK schrieb:

    Wie behandelst du denn in deinem C code einen fehler in der close-funktion?

    Die close() Funktion liefert einen Fehlercode, was ein Dtor in C++ nicht kann. Trotz aller C++ Magie, wie RAII, brauchst du für externe Ressourcen eine open() und eine close() Funktion und Exceptions in C++ sind nicht besser als if-Blöcke in C.



  • DEvent schrieb:

    Die close() Funktion liefert einen Fehlercode, ...

    Und was machst du dann, wenn die Funktion fehlschlägt? Wie willst du auf so einen Fehler reagieren? 🤡

    DEvent schrieb:

    Das war klar, dass Exceptions vorgeschlagen werden. Tatsache it aber, Exceptions C++ sind extrem nutzlos, bis auf den kleinen Vorteil, dass man wenigstens so Fehler in Operatoren abfragen kann.

    DEvent schrieb:

    ... und Exceptions in C++ sind nicht besser als if-Blöcke in C.

    Boah, was für eine konkrete Argumentation. Deine nicht vorhanden Argumente überzeugen micht völlig. Naja, um ehrlich zu sein, habe ich eher das Gefühl, dass du einfach Exceptions und C++ nicht verstanden hast.

    Wo haben wir nochmals *in seiner Clownkiste rumwühlt* ... aja, hier:
    Exception Handling
    Modernes Exception-Handling Teil 1
    Modernes Exception-Handling Teil 2

    So und jetzt geht der DEvent schön lesen, ja? Und kommt dann wieder mit richtigen Argumenten, statt nur irgendwelchen Parolen, welche nichts weiteres als heisse Luft sind.

    🤡



  • Bashar schrieb:

    fricky reloaded?

    Schon wieder einer, den Du verdächtigst diese "fricky" zu sein? Wer ist das überhaupt?

    PS: Ich warte immer noch auf glaubhafte Argumente pro-C und gegen C++. 😉



  • Clown schrieb:

    DEvent schrieb:

    Die close() Funktion liefert einen Fehlercode, ...

    Und was machst du dann, wenn die Funktion fehlschlägt? Wie willst du auf so einen Fehler reagieren? 🤡

    DEvent schrieb:

    Das war klar, dass Exceptions vorgeschlagen werden. Tatsache it aber, Exceptions C++ sind extrem nutzlos, bis auf den kleinen Vorteil, dass man wenigstens so Fehler in Operatoren abfragen kann.

    DEvent schrieb:

    ... und Exceptions in C++ sind nicht besser als if-Blöcke in C.

    Boah, was für eine konkrete Argumentation. Deine nicht vorhanden Argumente überzeugen micht völlig. Naja, um ehrlich zu sein, habe ich eher das Gefühl, dass du einfach Exceptions und C++ nicht verstanden hast.

    Wo haben wir nochmals *in seiner Clownkiste rumwühlt* ... aja, hier:
    Exception Handling
    Modernes Exception-Handling Teil 1
    Modernes Exception-Handling Teil 2

    So und jetzt geht der DEvent schön lesen, ja? Und kommt dann wieder mit richtigen Argumenten, statt nur irgendwelchen Parolen, welche nichts weiteres als heisse Luft sind.

    🤡

    Genau. Seitenlange Tutorials für so was simples wie Exceptions. Man braucht schon ein Diplomabschluss in C++tologie um eine exceptionsichere Stack-Klasse zu schreiben. 🙄
    Wenn ihr doch alles besser wisst, dann schreibt mir unwissenden doch ein Beispiel. Ich habe diesen Code hier in C, wie würdet ihr es in C++ lösen und wo sind die Vorteile:

    #ifdef LINUX
        RssconlinuxPortdata portdata = { { 0 } };
        strcpy(portdata.devicePath, "/dev/ttyUSB0\0");
        noiseread.portdata = &portdata;
        rssconlinuxSetupInterface(&noiseread);
    #endif
        if (!noiseOpen(&noiseread))
            { error(&noiseread, "error by noiseOpen()...\n"); return 1; }
            if (!noiseStart(&noiseread))
                { errorclose(&noiseread, "error by noiseStart()...\n"); goto close; }
                NoiseData noisedata = { 0 };
                if (!noiseRead(&noiseread, &noisedata, 1))
                    { errorclose(&noiseread, "error by noiseRead()...\n"); goto stop; }
    
    stop:
        noiseStop(&noiseread);
    close:
        noiseClose(&noiseread);
    


  • DEvent schrieb:

    Mein "Problem" mit C++ ist, dass ich dafür keine Verwendung habe,

    Nun, wenn ich einen Nagel reinhauen will, nehme ich auch einen Hammer und keinen Schraubenzieher. So gesehen, ist bis hier noch nichts anzukreiden.

    DEvent schrieb:

    es ist irgendwie obsolete. Für low-level kann man auch in C gut programmieren und den Code kapseln/abstrahieren.

    Ok, das siehst Du so. Andere Teilen diese Sicht anscheinend nicht.

    DEvent schrieb:

    Bitte wo hat mir jetzt die Verwendung von C++ Vorteile gebracht?

    Das kann man bei diesem kleinen Beispiel schlecht beurteilen. Es kann sein, dass bei dem Problem, was Du gelöst hast, die "optimale" C++ Lösung sehr ähnlich aussieht. Angenommen, das wäre so. Das hieße jetzt nicht, dass es nicht andere Problemstellungen gibt, die sich mit C++ Sprachmitteln viel eleganter lösen lassen. Andere Problemstellungen kann ich vielleicht mit einem Schraubenzieher viel eleganter lösen als nur mit einem Hammer, um bei dem Bild der Werkzeugkiste zu bleiben. Ich denke nicht, dass hier jemand behauptet hat, C++ sei die beste Sprache für jeden Job. Wenn Du für viele verschiedene, andere Problemstellungen immer noch C vorziehen würdest, dann liegt das wahrscheinlich an mindestens einem der folgenden Gründe:
    1. Du betrachtest nur einen sehr speziellen, Dich betreffenden Problembereich, in denen "ein Hammer vollkommen ausreicht und jedes beliebige andere Werkzeug keine Erleichterung darstellt".
    2. Du kennst die Sprache C++ nicht gut genug ("Du hältst einen Schraubenzieher für einen komisch aussehenden Hammer")

    DEvent schrieb:

    Nun zu hi-level, wie GUI, Server-Client, usw.
    In C++ ist nichts Standard, nicht mal so was essentielles wie eine String-Klasse.

    Was ist denn an std::string "nicht Standard"?

    DEvent schrieb:

    Wieso nicht also Python, Ruby, Java oder C# nehmen, die alle mit einer sehr reichhaltigen Standard-Bibliothek kommen, einen GC haben und Exceptions gut unterstützen.

    Nun, das ist eine komplett andere "Werkzeugkiste", die Du da aufmachst. Ich denke, C++ hat seine Existenzberechtigung. Es schafft low- und high-level Programmierung ohne Overhead ("zero overhead principle") zu kombinieren und ist damit auch bequem in "eingeschränkten Umgebungen" nutzbar.

    DEvent schrieb:

    Dann die Compilierzeit. Die Zeit, die C++ Entwickler nur da sitzen und auf das Ende des Compilers warten, kann man auch besser nutzen. In Java kann ich Änderungen in unter 1 Sekunde kompilieren für 5k SLOC Java Klasse. Ich brauche nicht das gesamte Projekt neu zu übersetzen, wenn sich mal eine Interface einer Klasse ändert. Ein Projekt von 30k SLOC Java ist auch in unter 5 Sekunden komplett kompiliert.

    Wenn sich da etwes an einer Schnittstelle ändert, müsste man dann nicht auch den Code anpassen, der diese Schnittstelle benutzt? Und warum sollte man anderen Code neu kompilieren, der überhaupt nichts von dieser Schnittstelle weiß? Ich kenne die Argumentation etwas anders. Da regen sich Leute auf, weil sie nur Implementierungsdetails ändern und einiges neu kompilieren müssen -- zB wenn sie private Objekt-Elemente hinzufügen/verändern/entfernen und dies natürlich im "Header verraten". Nun, in C und C++ hast Du die Wahl. Entweder verrätst Du, wie ein Objekt der Klasse aufgebaut ist (im Header). Das erlaubt Dir das Einbetten dieser Objekte in andere oder das Anlegen auf dem Stack. Oder, Du versteckst Implementierungsdetails ("pimpl", "compiler firewall idiom"). Dann beschränkst Du Dich aber auch auf dynamisches Anlegen/Löschen und Zugriff über ein "Handle" (zB Zeiger) und Änderungen an der Implementierung erfordern kein Neukompilieren der Übersetzungseinheiten, die nur einen Header einbinden, welcher keine Implementierungsdetails verrät. In Java kannst Du Dir das nicht aussuchen. Dort gibt es nur "Handles" (auch bekannt unter "Referenzen").

    DEvent schrieb:

    Bibliothekenverwaltung ist in C++ auch aus dem letztem Jahrhundert. In Java kann ich jede Jar nehmen und in mein Projekt integrieren. In C++ muss ich entweder erst das Projekt übersetzen (und dafür brauche ich sämtliche Abhängigkeiten) oder hoffen das es für mein System, Architektur und Compiler(!) eine Bibliothek gibt.

    Nun, das ist prinzipiell keine Einschränkung, die durch die Sprache selbst gemacht wird. C++ standardisiert eben nur die Sprache an sich + Standardbibliothek und nicht, wie das auszusehen hat, was der Compiler ausspuckt und entgegennehmen können muss bzgl Bibliotheken. Daher ist diese Sache "implementierungsabhängig". Man sollte sich jedenfalls mal mit dem einen oder anderen Build-System beschäftigen, welches systemspezifische Dinge idealerweise abstrahiert.

    Kann das sein, dass Du nur Java und C kennst und glaubst, etwas über C++ zu wissen? Wie viele Erfahrungen hast Du mit C++ gemacht? Wie lange hast Du C++ programmiert? Welche Bücher hast Du zu C++ gelesen?



  • DEvent schrieb:

    Ich habe diesen Code hier in C, wie würdet ihr es in C++ lösen und wo sind die Vorteile:

    #ifdef LINUX
        RssconlinuxPortdata portdata = { { 0 } };
        strcpy(portdata.devicePath, "/dev/ttyUSB0\0");
        noiseread.portdata = &portdata;
        rssconlinuxSetupInterface(&noiseread);
    #endif
        if (!noiseOpen(&noiseread))
            { error(&noiseread, "error by noiseOpen()...\n"); return 1; }
            if (!noiseStart(&noiseread))
                { errorclose(&noiseread, "error by noiseStart()...\n"); goto close; }
                NoiseData noisedata = { 0 };
                if (!noiseRead(&noiseread, &noisedata, 1))
                    { errorclose(&noiseread, "error by noiseRead()...\n"); goto stop; }
    
    stop:
        noiseStop(&noiseread);
    close:
        noiseClose(&noiseread);
    

    Das ist leicht. Wird siwas werden wie

    RssconlinuxPortdata portdata("/dev/ttyUSB0\0");
    NoiseData noisedata(portdata);
    x=noisedata.read();
    

    Aber genau kann man's nicht sagen, weil der C-Code nicht verständlich ist. Vorteile gibts keine, außer vielleich ein wenig Fehlersicherheit und Entlasteung des Programmierers von trivialen Aufgaben.



  • DEvent schrieb:

    Clown schrieb:

    So und jetzt geht der DEvent schön lesen, ja? Und kommt dann wieder mit richtigen Argumenten, statt nur irgendwelchen Parolen, welche nichts weiteres als heisse Luft sind.

    Genau. Seitenlange Tutorials für so was simples wie Exceptions. Man braucht schon ein Diplomabschluss in C++tologie um eine exceptionsichere Stack-Klasse zu schreiben. 🙄

    Oh, tut mir leid, ich wusste nicht, dass du nicht lesen kannst oder dass es dir so schwer fällt, ein paar kurze Seiten zu lesen. Naja, dann bleibt dir wohl wirklich nichts anderes übrig, als irgendwelche Parolen zu machen, welche nichts weiteres als heisse Luft sind. Mein Beileid.

    🤡



  • [quote="volkard"]

    DEvent schrieb:

    Ich habe diesen Code hier in C, wie würdet ihr es in C++ lösen und wo sind die Vorteile:

    #ifdef LINUX
        RssconlinuxPortdata portdata = { { 0 } };
        strcpy(portdata.devicePath, "/dev/ttyUSB0\0");
        noiseread.portdata = &portdata;
        rssconlinuxSetupInterface(&noiseread);
    #endif
        if (!noiseOpen(&noiseread))
            { error(&noiseread, "error by noiseOpen()...\n"); return 1; }
            if (!noiseStart(&noiseread))
                { errorclose(&noiseread, "error by noiseStart()...\n"); goto close; }
                NoiseData noisedata = { 0 };
                if (!noiseRead(&noiseread, &noisedata, 1))
                    { errorclose(&noiseread, "error by noiseRead()...\n"); goto stop; }
    
    stop:
        noiseStop(&noiseread);
    close:
        noiseClose(&noiseread);
    

    Das ist leicht. Wird siwas werden wie

    RssconlinuxPortdata portdata("/dev/ttyUSB0\0");
    NoiseData noisedata(portdata);
    x=noisedata.read();
    

    Er wollte ein C++ Beispiel, nicht Java.



  • OOP Guy schrieb:

    Er wollte ein C++ Beispiel, nicht Java.

    In Java ist es üblich, die Reader so auf die Files zu setzen. Das darf man in C++ auch.



  • volkard schrieb:

    OOP Guy schrieb:

    Er wollte ein C++ Beispiel, nicht Java.

    In Java ist es üblich, die Reader so auf die Files zu setzen. Das darf man in C++ auch.

    Gut, dann machen wir aus Deinem Code wieder C:

    RssconlinuxPortdata *portdata = create_portdata("/dev/ttyUSB0\0");
    NoiseData *noisedata = create_noisedata(portdata);
    x = noisedata->read();
    

    Und was haben wir jetzt bewiesen? 😕



  • Exceptionsicherheit ist in jeder Sprache mit Exceptions ein Problem. In Sprachen mit einem GC muss man sich nur um den Teil mit der Speicherfreigabe keine Sorgen machen. Aber das Datenstrukturen in einem ungültigen Zustand bleiben oder andere Ressourcen nicht richtig freigegeben werden.



  • OOP Guy schrieb:

    volkard schrieb:

    OOP Guy schrieb:

    Er wollte ein C++ Beispiel, nicht Java.

    In Java ist es üblich, die Reader so auf die Files zu setzen. Das darf man in C++ auch.

    Gut, dann machen wir aus Deinem Code wieder C:

    RssconlinuxPortdata *portdata = create_portdata("/dev/ttyUSB0\0");
    NoiseData *noisedata = create_noisedata(portdata);
    x = noisedata->read();
    

    Und was haben wir jetzt bewiesen? 😕

    Daß Du in C keine Fehlerbehandlung hast und es doch so wirr wie oben machen mußt. In C++ werfen Konstruktoren oder read bei Fehlern einfach Exceptions und Destruktoren räumen auf. Damit muß ich mich dann nichtmehr belasten.



  • rüdiger schrieb:

    Exceptionsicherheit ist in jeder Sprache mit Exceptions ein Problem. In Sprachen mit einem GC muss man sich nur um den Teil mit der Speicherfreigabe keine Sorgen machen. Aber das Datenstrukturen in einem ungültigen Zustand bleiben oder andere Ressourcen nicht richtig freigegeben werden.

    Sprachen mit Exceptions haben "finally" oder was vergleichbares. Ungültigen Zustand von Datenstrukturen hat man nur, wenn die Exception zu früh geworfen wird.



  • volkard schrieb:

    In C++ werfen Konstruktoren oder read bei Fehlern einfach Exceptions und Destruktoren räumen auf. Damit muß ich mich dann nichtmehr belasten.

    Aber der Programmierer der Klassen muss die Fehlerbehandlung implementiert haben, gleiches könnte der Programmierer des C-codes tun.

    RssconlinuxPortdata *portdata = create_portdata("/dev/ttyUSB0\0");  // Fehler: portdata ist null
    NoiseData *noisedata = create_noisedata(portdata); // Fehler: Aufruf mit null erzeugt ungültiges NoiseData-Objekt
    x = noisedata->read(); // Fehler: ungültiges Objekt gibt immer einen Fehlercode zurück
    

    Und was haben wir jetzt damit bewiesen? 😕


Anmelden zum Antworten