Warum lassen C/C++ Compiler soviel Müll zu?



  • Antoras schrieb:

    Es macht einen kleinen Unterschied ob ich durch vorausschauendes Programmieren, oder durch sofortige Fehlersuche Fehler finde. Erstere umgeht man indem man einen Fehler ausgibt wenn das Programm bestimmte Ressourcen, die es zum arbeiten benötigt, nicht findet (Diese Fehlerbehandlung kann einem die IDE nicht abnehmen). Letztere umgeht man nur durch gründliches Durcharbeiten des Sourcecodes. Gemeint sind hier bspw. Rechtschreibfehler,

    In C++ versteht man unter vorausschauendem Programmieren etwas ganz anderes, als daß man eine Exception wirft, wenn ein eine Datei nicht da ist. Man versteht darunter, daß man seine niederen Funktionen so gestaltet, daß viele typische Programmierfehler zur Compilezeit herausgefischt werden. Falls Dir mal das Buch "Effektiv C++ programmieren" über den Weg läuft, schau schnell rein.



  • volkard schrieb:

    Antoras schrieb:

    Gemeint sind hier bspw. Rechtschreibfehler, die dazu führen, dass eine Funktion, die nicht existiert aufgerufen wird (Und die passieren jedem mal). Eine IDE zeigt mir so etwas sofort an und ich kann es beheben. Mit einem normalen Editor muss ich erst anfangen zu kompilieren, damit mir der Compiler den Fehler anzeigen kann.

    Und wenn die IDE nicht alles findet, hagelt es Exceptions zur Laufzeit. Natürlich ein paar davon beim Kunden. Sie kann eh nicht viel finden. In C++ schon gar nicht. Ich glaube, es würde mich nur verwirren, wenn die Hälfte der Tippfehler von der IDE angezeigt werden würden und die andere Hälfte vom Compiler.

    Dumm nur, dass die IDE einfach auch nen Compiler verwendet und somit alle Fehler findet und nicht nur die Hälfte. Vielleicht solltest du erst mal so ne Java IDE verwenden, vor du Vermutungen aufstellst.



  • volkard schrieb:

    audacia schrieb:

    volkard schrieb:

    Sicherlichhat jeder C++-Programmierer oft ein Auge auf Java, weil da mal was einfacher geht.

    Und das ja nicht zu Unrecht. Eine moderne objektorientierte Hochsprache ohne das geringste Bißchen Reflection scheint einem schon manchmal etwas retardiert.

    Och, nöö. 99.93% der Programmiersachen gehen einfacher( ,womit auch fehlerfreier) und schneller ohne.

    Wenn du Shareware oder Numbercrunching-Software entwickelst, mag das zutreffen.

    volkard schrieb:

    Ups, C++ schafft alle, manchmal haut man halt einen C-Makro rein oder frickelt sonstwas.

    Versteh ich nicht.

    volkard schrieb:

    Einigen wir uns mal drauf, daß Java eh außen vor ist, weil es ungefähr gar nichts kann zu enormen Kosten und das mit einer unglaublich bizarren Syntax im vergleich zum Erreichten.

    Leicht übertrieben, aber nicht ganz falsch. Fürs Einigen ist es mir etwas zu stark formuliert 😉

    Jedenfalls tun sich C++ und Java in puncto syntaktischer Redundanz nicht viel, und auch die Performance einer Java-Anwendung ist viel näher an C++ denn an anderen modernen Sprachen. Die jeweiligen Schwächen der Sprachen liegen anderswo.

    tja schrieb:

    Vielleicht solltest du erst mal so ne Java IDE verwenden, vor du Vermutungen aufstellst.

    +1.



  • audacia schrieb:

    hustbaer schrieb:

    warum????? schrieb:

    Zeus schrieb:

    Wegen der Rekursion in der Grammatik. IfStatement, WhileStatement sind Statement und hinter dem Kopf darfst du weitere Statements schreiben - recht einfach. Aber verhindert halt nicht, das schreiben vom dummen Code.

    Aber warum braucht C++ Code dann soviel länger zum Compilieren als Java Code, der eigentlich viel eingeschränkter ist?

    weil C++ viel komplizierter zu compilieren ist als Java.

    argument dependent lookup, implizite konvertierungen, templates, overload resolution -> in kombination ist das viel arbeit für einen compiler

    Das machts alles nicht aus; ein guter C++-Compiler kann durchaus die Geschwindigkeit eines Delphi-/Java-/C#-/Whatever-Compilers erreichen. Ausschlaggebend ist primär die Menge.

    Wenn man kaum templates verwendet mag das zutreffen.



  • hustbaer schrieb:

    Wenn man kaum templates verwendet mag das zutreffen.

    Das hatten wir schon:

    knivil schrieb:

    (Templates mal aussen vor, da ich Endlosschleifen produzieren kann)



  • ach ja, nochwas. ich glaube, was mir an c++ zuerst negativ aufgefallen ist: wie man statische klassenvariablen anlegen muss. einmal in der klassendefinition und dann noch mal ausserhalb. da hatte stroustrup wohl 'nen richtigen blackout, als er sich das einfallen liess.
    🙂



  • Basher schrieb:

    ach ja, nochwas. ich glaube, was mir an c++ zuerst negativ aufgefallen ist: wie man statische klassenvariablen anlegen muss. einmal in der klassendefinition und dann noch mal ausserhalb. da hatte stroustrup wohl 'nen richtigen blackout, als er sich das einfallen liess.
    🙂

    Im Header deklarieren. In der Implementierungsdatei definieren (=Speicherplatz besorgen). Ist doch in C genauso. Warum wundert Dich das?



  • volkard schrieb:

    Im Header deklarieren. In der Implementierungsdatei definieren (=Speicherplatz besorgen). Ist doch in C genauso. Warum wundert Dich das?

    in C gibts doch keine statischen struct-members. auch wenn C++ anfänglich eine erweiterung von C sein sollte, so macht es doch wenig sinn, sich bei etwas völlig neuem zu sehr an C zu orientieren.
    btw, mas macht C++ eigentlich bei sizeof(cpp_klasse), werden statische members mitgezählt oder nicht?
    🙂



  • btw, mas macht C++ eigentlich bei sizeof(cpp_klasse), werden statische members mitgezählt oder nicht?

    Probiere es aus! Aber da sizeof z.B. bei Speicherreservierung gebraucht wird und statische Member nicht in Objekten gespeichert werden, ... naja du kannst sicher fortsetzen 🙂 Wo aber sollte man noch sizeof in reinem C++ verwenden? Auch liefert der erste Treffer bei google die Antwort, falls Logik nicht ausreicht.



  • vor allem - mußte man Klassenvariablen unbedingt auch mit 'static' einleiten, wo dieses Wort ja schon in C doppelt belegt ist.



  • u-ser_l schrieb:

    vor allem - mußte man Klassenvariablen unbedingt auch mit 'static' einleiten, wo dieses Wort ja schon in C doppelt belegt ist.

    ja stimmt, das ist auch doof. man könnte sich doch was mit referenzen bauen, etwa so:

    int staticvar = 12;
    
    struct test
    {
      int &j;
    
      test() : j(staticvar)
      {
        j++;
      }
    };
    

    ^^ 'j' verhält sich wie eine C++ klassenvariable, obwohl kein static davor steht, d.h. diese sonderregelung mit 'static' in der klasse usw, wäre garnicht nötig gewesen.
    🙂



  • Basher schrieb:

    u-ser_l schrieb:

    vor allem - mußte man Klassenvariablen unbedingt auch mit 'static' einleiten, wo dieses Wort ja schon in C doppelt belegt ist.

    ja stimmt, das ist auch doof. man könnte sich doch was mit referenzen bauen, etwa so:

    int staticvar = 12;
    
    struct test
    {
      int &j;
    
      test() : j(staticvar)
      {
        j++;
      }
    };
    

    ^^ 'j' verhält sich wie eine C++ klassenvariable, obwohl kein static davor steht, d.h. diese sonderregelung mit 'static' in der klasse usw, wäre garnicht nötig gewesen.
    🙂

    nö.
    einfacher wirds doch durch mehr worte, nicht durch weniger. wie willste denn hier begründen, daß sizeof(test)==1?
    denn bei
    struct test
    {
    int &j;

    test() : j(staticvar)
    {
    j++;
    }
    test(int& nsv) : j(nsv)
    {
    j++;
    }
    };
    [/code]
    wird sizeof(test)==sizeof(void*) sein.



  • Basher schrieb:

    u-ser_l schrieb:

    vor allem - mußte man Klassenvariablen unbedingt auch mit 'static' einleiten, wo dieses Wort ja schon in C doppelt belegt ist.

    ja stimmt, das ist auch doof. man könnte sich doch was mit referenzen bauen, etwa so:

    int staticvar = 12;
    
    struct test
    {
      int &j;
    
      test() : j(staticvar)
      {
        j++;
      }
    };
    

    ^^ 'j' verhält sich wie eine C++ klassenvariable, obwohl kein static davor steht, d.h. diese sonderregelung mit 'static' in der klasse usw, wäre garnicht nötig gewesen.
    🙂

    Ach! Dann kann ich also mit deiner "statischen" Variable problemlos das Folgende schreiben?

    int main() {
    
       std::cout << test::j << std::endl;
       return 0;
    }
    

    Geniale Idee!

    Stefan.



  • volkard schrieb:

    wie willste denn hier begründen, daß sizeof(test)==1?

    kann man das überhaupt begründen, oder isses nur willkürlich so festgelegt worden?

    volkard schrieb:

    denn bei

    struct test
    {
      int &j;
    
      test() : j(staticvar)
      {
        j++;
      }
      test(int& nsv) : j(nsv)
      {
        j++;
      }
    };
    

    wird sizeof(test)==sizeof(void*) sein.

    naja, das könnte man so begründen, dass jedes objekt, technisch gesehen, einen zeiger auf das gemeinsam genutzte klassenobjekt haben muss. aber eigentlich hatte ich erhofft, dass ein cpp-compiler die referenz wegoptimiert.

    DStefan schrieb:

    Ach! Dann kann ich also mit deiner "statischen" Variable problemlos das Folgende schreiben?

    int main() {
    
       std::cout << test::j << std::endl;
       return 0;
    }
    

    hast recht, das geht so nicht. man muss ein objekt haben und dann dieses :: gegen einen punkt tauschen. aber das wäre doch nicht schlimm.
    🙂



  • Basher schrieb:

    volkard schrieb:

    wie willste denn hier begründen, daß sizeof(test)==1?

    kann man das überhaupt begründen, oder isses nur willkürlich so festgelegt worden?

    volkard schrieb:

    denn bei

    struct test
    {
      int &j;
    
      test() : j(staticvar)
      {
        j++;
      }
      test(int& nsv) : j(nsv)
      {
        j++;
      }
    };
    

    wird sizeof(test)==sizeof(void*) sein.

    naja, das könnte man so begründen, dass jedes objekt, technisch gesehen, einen zeiger auf das gemeinsam genutzte klassenobjekt haben muss. aber eigentlich hatte ich erhofft, dass ein cpp-compiler die referenz wegoptimiert.

    Hast Du den zweiten Konstruktor gesehen? Den, der j nicht an die gemeinsame Variable bindet.



  • volkard schrieb:

    Hast Du den zweiten Konstruktor gesehen? Den, der j nicht an die gemeinsame Variable bindet.

    ja, aber der hat doch nichts damit zu tun, dass sizeof(test) == 1 ist. mit dem konstruktor wolltest du andeuten, dass man meine methode aushebeln kann? aber das ist doch nichts ungewöhnliches für in C++, wo man schnell man unsinn produziert, wenn man sich nicht an bestimmte regeln hält.
    🙂



  • Basher schrieb:

    volkard schrieb:

    Hast Du den zweiten Konstruktor gesehen? Den, der j nicht an die gemeinsame Variable bindet.

    ja, aber der hat doch nichts damit zu tun, dass sizeof(test) == 1 ist.

    ob 1 oder 0 ist hier egal. es geht um den unterschied zwischen 1/0 und 4. darum, daß die referenz durch den zweiten konstruktor nicht wegoptimierbar ist. darum, daß test::j dann nur überhaupt denkbar sein würde, wenn der zweite konstruktor nicht da wäre. kurzum, es wäre komplizierter als mit einem schlüsselwort, was gemeinsam benutze daten anzeigt.

    mit dem konstruktor wolltest du andeuten, dass man meine methode aushebeln kann?

    Nein.

    aber das ist doch nichts ungewöhnliches für in C++, wo man schnell man unsinn produziert, wenn man sich nicht an bestimmte regeln hält.
    🙂

    Aufpassen muß man in C noch viel mehr, habe ich mir sagen lassen. Und wie man an den vielen Abstürzen und Sicherheitslücken von C-Programmen sieht, klappt es selten.



  • Basher schrieb:

    aber das ist doch nichts ungewöhnliches für in C++, wo man schnell man unsinn produziert, wenn man sich nicht an bestimmte regeln hält.
    🙂

    Das ist nichts ungewoehnliches fuer die meisten Sprachen inklusive Java.



  • volkard schrieb:

    es wäre komplizierter als mit einem schlüsselwort, was gemeinsam benutze daten anzeigt.

    gut, das sehe ich ein. trotzdem finde ich das anlegen von statischen membern in C++ klassen denkbar misslungen. es wäre (für den benutzer) angenehmer, in die klassendefinition z.b. 'static int j = 12;' zu schreiben und weiter nix mehr. um den rest hat sich der compiler zu kümmern.

    volkard schrieb:

    Aufpassen muß man in C noch viel mehr, habe ich mir sagen lassen.

    dann hat man dir quatsch erzählt. C ist schlichter als C++, daher gibt's da auch weniger mögliche fehlerquellen.
    🙂



  • hustbaer schrieb:

    audacia schrieb:

    hustbaer schrieb:

    warum????? schrieb:

    Zeus schrieb:

    Wegen der Rekursion in der Grammatik. IfStatement, WhileStatement sind Statement und hinter dem Kopf darfst du weitere Statements schreiben - recht einfach. Aber verhindert halt nicht, das schreiben vom dummen Code.

    Aber warum braucht C++ Code dann soviel länger zum Compilieren als Java Code, der eigentlich viel eingeschränkter ist?

    weil C++ viel komplizierter zu compilieren ist als Java.

    argument dependent lookup, implizite konvertierungen, templates, overload resolution -> in kombination ist das viel arbeit für einen compiler

    Das machts alles nicht aus; ein guter C++-Compiler kann durchaus die Geschwindigkeit eines Delphi-/Java-/C#-/Whatever-Compilers erreichen. Ausschlaggebend ist primär die Menge.

    Wenn man kaum templates verwendet mag das zutreffen.

    Die Standardbibliotheken sind prall gefüllt mit Template-Code. Du hast zwar insofern Recht, als daß sich die intensive Nutzung von Templates deutlich in den Übersetzungszeiten niederschlägt, aber selbst dann ist der Unterschied der zu übersetzenden Zeilen zwischen einem C++- und vergleichbaren Java-, C#- oder Delphi-Programmen derart deutlich (Faktor 10000?), daß der zusätzliche Aufwand für Templates auch nicht mehr viel ausmacht.

    Die Zeilenzahlexplosion kann man recht gut mit PCHs in den Griff bekommen; wenn der Compiler in der Lage ist, uninstantiierte Templates zu parsen, ebenso das Template-Problem. Allerdings trifft das, glaube ich, gerade mal aufs EDG-Frontend zu (das überall sonst fehlende Two phase name lookup läßt das jedenfalls vermuten).

    knivil schrieb:

    Wo aber sollte man noch sizeof in reinem C++ verwenden?

    Bei Variadic Templates, um die Anzahl der Argumente herauszufinden.

    Basher schrieb:

    trotzdem finde ich das anlegen von statischen membern in C++ klassen denkbar misslungen. es wäre (für den benutzer) angenehmer, in die klassendefinition z.b. 'static int j = 12;' zu schreiben und weiter nix mehr. um den rest hat sich der compiler zu kümmern.

    War, glaube ich, für C++ 0x geplant.


Anmelden zum Antworten