Warum verwendet ueberhaupt noch irgendjemand C?



  • Ich denke STL (Person) bringt es auf den Punkt: http://nuwen.net/gcc.html#whynotc



  • Einfachheit würde ich sagen. Der kompilierte Code ist außerdem auch deutlich kompakter, was bei Microcontrollern nicht unerheblich ist.



  • Es gibt einen Grund, wieso solche Lobgesänge ausschliesslich von Template-Fanatikern kommen. C++-Programmierer haben oft lack of pragmatism.

    Wenn du ein Softwareprojekt in C anfängst, bekommst du Pragmatiker und das Projekt geht vorwärts.
    Wenn du ein Softwareprojekt in C++ anfängst, bekommst du übergeschnappte Template-Fanatiker und die Programmierer verfangen sich in Design-Überlegungen und bauen unnötige Bibliotheken. Nichts geht mehr vorwärts. Nenn mir mal ein grösseres Software-Projekt, das alle Regeln von STL befolgt.

    C++ ist gut, wenn man pragmatisch bleibt und nicht übermütig in der Nutzung der Sprachfeatures wird. Aber die Richtung von STL ist gefährlich, so wird man bestenfalls Library-Developer.



  • Warum gibt es ueberhaupt noch Leute, für die nur die Programmiersprachen C, C++ und Java existieren?



  • pragmatiker schrieb:

    Wenn du ein Softwareprojekt in C anfängst, bekommst du Pragmatiker und das Projekt geht vorwärts.

    Ich kann mit C gar nichts anfangen, weil mir die Datenstrukturen fehlen.
    Intrusive Lists, per Hand zu kopierende Arrays, strings per hand zusammenschneiden u.s.w. nevt nur noch und der algorithm-Header mit dem ganzen Kram ist auch hilfreich, weil man nuetzliche Algorithmen hat, ohne an einen Datentyp oder Container gebunden zu sein. In C++ kann ich einfach anfangen und mir ein Programm basteln, ohne mir ueber die genaue Objektverwaltung Gedanken zu machen, aber ich kann spaeter immernoch sehr einfach eine Datenstruktur durch eine effizientere austauschen.

    Fuer die Low-Level-Komponenten eines Betriebssystems oder performancekritische Teile innerhalb eines C++-Programms finde ich es sehr hilfreich, aber sonst nervt es.



  • dinosaur schrieb:

    Warum gibt es ueberhaupt noch Leute, für die nur die Programmiersprachen C, C++ und Java existieren?

    Welche Sprachen verwendest du denn? 😉



  • raptor49 schrieb:

    dinosaur schrieb:

    Warum gibt es ueberhaupt noch Leute, für die nur die Programmiersprachen C, C++ und Java existieren?

    Welche Sprachen verwendest du denn? 😉

    Python und Perl.

    Testweise auch Haskell und Rust.

    C++ nur, wenn die Performance nachweisbar nicht ausreichend ist, also quasi nie.

    Marthog schrieb:

    In C++ kann ich einfach anfangen und mir ein Programm basteln, ohne mir ueber die genaue Objektverwaltung Gedanken zu machen, aber ich kann spaeter immernoch sehr einfach eine Datenstruktur durch eine effizientere austauschen.

    Wenn du C++ für Projekte verwendest, die man einfach runterschreiben kann ohne auf Performance zu achten, hast du die falsche Sprache gewählt.


  • Mod

    dinosaur schrieb:

    Wenn du C++ für Projekte verwendest, die man einfach runterschreiben kann ohne auf Performance zu achten, hast du die falsche Sprache gewählt.

    Das schöne ist doch, dass ein halbwegs geübter C++-Programmierer nicht auf Performance achten muss, da es automatisch schnell ist. Er muss nur die berühmt berüchtigten Möglichkeiten vermeiden, sich das Bein abzuschießen.

    Ich schreibe meine Programme einfach so runter. Und wenn ich hinterher versuche irgendetwas zu optimieren, dann sind die einzigen Optionen, die ich noch finde, technische Optimierungen wie Cache-Misses, auf die man während des Programmierens als Normalsterblicher gar nicht achten kann.



  • dinosaur schrieb:

    Python und Perl.

    Was für Programme sind das?! Programmierst du mit mehreren Threads? Die Umsetzung von Multithreading in Skriptsprachen ist ein Witz, weswegen ich diese Sprachen für größere Projekte nicht ernst nehmen kann. Und von Laufzeitfehlern die durch Typprüfungen aufgefallen wären, halte ich auch nichts. IDEs kommen dadurch was Code-Completion anbelangt, auch an ihre Grenzen.

    L. G.,
    IBV



  • C ist doch nur was für Frickler! 👎 😮



  • SeppJ schrieb:

    Ich schreibe meine Programme einfach so runter. Und wenn ich hinterher versuche irgendetwas zu optimieren, dann sind die einzigen Optionen, die ich noch finde, technische Optimierungen wie Cache-Misses, auf die man während des Programmierens als Normalsterblicher gar nicht achten kann.

    Kann ich kaum glauben. Du müsstest quasi auf alle Container/Algorithmen der STL verzichten (vielleicht bis auf std::vector). Da kann ich mir nur eine stupide Simulation drunter vorstellen. Möchtest du ein Beispiel bringen?

    IBV schrieb:

    dinosaur schrieb:

    Python und Perl.

    Was für Programme sind das?!

    Gut, in Perl mache ich nur kleine Skripte.

    Programmierst du mit mehreren Threads? Die Umsetzung von Multithreading in Skriptsprachen ist ein Witz, weswegen ich diese Sprachen für größere Projekte nicht ernst nehmen kann.

    Ja ich verwende Multithreading und hatte damit noch nie Probleme.

    Und von Laufzeitfehlern die durch Typprüfungen aufgefallen wären, halte ich auch nichts.

    Hatte ich noch nie ein Problem damit. Das fällt schnell auf. Insgesamt ist die Zeitersparnis nicht dauernd ein verbose typing zu haben grösser als der Nachteil.

    IDEs kommen dadurch was Code-Completion anbelangt, auch an ihre Grenzen.

    Ich verwende keine Code-Completion, auch in C++ nicht. Das lenkt mich nur ab.



  • dinosaur schrieb:

    Kann ich kaum glauben. Du müsstest quasi auf alle Container/Algorithmen der STL verzichten (vielleicht bis auf std::vector).

    Das ist Quatsch, weil ein Großteil eines Programms oft völlig Performanceunkritisch ist.

    dinosaur schrieb:

    Hatte ich noch nie ein Problem damit. Das fällt schnell auf. Insgesamt ist die Zeitersparnis nicht dauernd ein verbose typing zu haben grösser als der Nachteil.

    Also mich hat das enorm gestört, insbesondere wenn man noch mal schnell etwas testweise ändern will, treten dann teilweise Fehler in Randsituationen zur Laufzeit auf die einem der Compiler sonst sofort mitgeteilt hätte. (Ich meine nicht umsonst gibt es static_assert.) Vermutlich gewöhnt man sich irgendwann daran, aber dass es Zeit spart kann ich mir jetzt nicht vorstellen. (Außer bei sehr kleinen Scripts.)



  • Ich kann mir auch nicht vorstellen, dass es Zeit spart, wenn man sich dran gewöhnt hat. Abgesehen davon, dass mich das auch enorm stört, dass einige Fehler unnötigerweise erst bei irgendwelchen Sonderfällen zur Laufzeit auffallen. Warum sollte die Zeitersparnis beim Tippen wichtig sein? Das ist doch völlig irrelevant. Viel wichtiger ist, später im Programm zu sehen, was man hat und was das ist. Bei jedem größeren Programm finde ich das eigentlich schon völlig unwartbar. Wenn ich irgendwo eine Funktion sehe, die einen Parameter x bekommt, woher soll ich den wissen, was das x ist und was das kann? Ist doch viel besser, wenn man den Typen gleich kennt, dann kann man sich den Typen anschauen und man kann auch sonst nichts falsch machen, weil der Compiler einen dabei unterstützt. Sonst fängt man an zu suchen, wo die Funktion alles aufgerufen wird, um rauszufinden, was man da reinbekommt, dann geht das so immer weiter, weil der Parameter über mehrere Funktionen durchgereicht wird, dann wird der Parameter irgendwo rausgeholt, wo dann auch überhaupt nicht klar ist, was das ist und man muss suchen, wo da was reingesteckt wird usw... Ich werde nie verstehen, wie jemand meinen kann, so könnte man effizienter entwickeln.
    Ich musste früher auch paar größere Perl und Python Programme pflegen, die nicht von mir waren, und habe ewig nach sowas gesucht. Klar, ist ja nicht mein Programm und ich kenn mich nicht aus. Nur hätte ich in einer statisch typisierten Sprache solche Probleme überhaupt nicht. Im Grunde genommen hätte ich sowas nicht mal suchen müssen, weil auch die Fehler an sich waren oft ebenfalls auf falsche Typen zurückzuführen. Es gibt irgendwelche Strukturen oder Plugins oder was auch immer, dann wird irgendwo irgendwas geändert, und eine unwichtige Funktion vergisst man dabei und fünf Jahre später fällt auf, dass "irgendwas" nicht geht.



  • Der Verlust der statischen Typsicherheit wirkt sich nicht nur auf Autocompletion aus, auch Refactoring wird zur Hölle. Du änderst in C++ die Semantik eines Parameters und änderst dessen Typ? Kein Problem, Aufrufcode kompiliert nicht. Skriptsprache: Manuell alle Aufrufe suchen und ändern, hoffen dass man keinen vergessen hat. Funktion umbenennen? Alt+Shift+R in VAX, fertig. Funktioniert semantisch und nicht nur Search&Replace, kennt daher Scopes. Zugriff auf Variable, die noch nicht existiert? Kompiliert in C++ nicht, Laufzeitfehler in Skriptsprachen. Das geht endlos weiter... Codeanalyse-Tools können einen kleinen Teil solcher Fehler auffangen, aber prinzipbedingt lange nicht alles.

    Ich merke alleine schon, wenn ich in Java entwickle, wie oft ich NullPointerException s habe -- nicht selten durch vage dokumentierte Schnittstellen, die in Spezialfällen unerwartet null zurückgeben. In C++ dereferenziere ich nie Nullzeiger, weil ich mit dem Typen ausdrücken kann, ob nullptr ein gültiger Zustand ist. Insbesondere kann ich ausdrücken, dass ein Objekt immer konstruiert zu sein hat. Anhand einer Funktionssignatur in C++ kann man enorm viel über die Semantik ablesen, besonders im Bezug auf Besitzverhältnisse und Lese-/Schreibrechte. Bei Java kann man nur den unqualifizierten Datentypen erkennen, bei dynamisch typisierten Sprachen gar nichts.

    Bei kleineren Skripten und Prototypen oder sehr dynamischen Programmen spielen dynamisch typisierte Sprachen ihre Stärken aus. Bei "klassischen" Softwareprojekten ab einer gewissen Komplexität kann statische Typsicherheit massiv viel ausmachen.



  • Kellerautomat schrieb:

    http://nuwen.net/gcc.html#whynotc

    C++ is the best general purpose programming language.

    Lol, bis dahin gefiel mir der Artikel eigentlich recht gut. 😃



  • cooky451 schrieb:

    dinosaur schrieb:

    Kann ich kaum glauben. Du müsstest quasi auf alle Container/Algorithmen der STL verzichten (vielleicht bis auf std::vector).

    Das ist Quatsch, weil ein Großteil eines Programms oft völlig Performanceunkritisch ist.

    Genau auf das wollte ich raus. Für den Grossteil eines Programms ist C++ völlig Overkill -- aus Sicht der Performance und des Syntaxoverheads. Wenn niemand Performanceschwierigkeiten mit der Standardbibliothek bekommt dann ist offenbar Performance für die meisten kein Grund, C++ zu wählen.

    dinosaur schrieb:

    Hatte ich noch nie ein Problem damit. Das fällt schnell auf. Insgesamt ist die Zeitersparnis nicht dauernd ein verbose typing zu haben grösser als der Nachteil.

    Also mich hat das enorm gestört, insbesondere wenn man noch mal schnell etwas testweise ändern will, treten dann teilweise Fehler in Randsituationen zur Laufzeit auf die einem der Compiler sonst sofort mitgeteilt hätte. (Ich meine nicht umsonst gibt es static_assert.)

    Glücklicherweise kann man den Fehler gleich on the fly korrigieren und muss nicht stundenlang auf den Compiler warten.

    Nebenbei gibt es gute Tools, pyflakes fängt dir einige Fehler während dem Code ab.

    Abgesehen davon, dass mich das auch enorm stört, dass einige Fehler unnötigerweise erst bei irgendwelchen Sonderfällen zur Laufzeit auffallen.

    Sonderfälle fängt einem das Typsystem auch nicht ab.

    Warum sollte die Zeitersparnis beim Tippen wichtig sein? Das ist doch völlig irrelevant. Viel wichtiger ist, später im Programm zu sehen, was man hat und was das ist. Bei jedem größeren Programm finde ich das eigentlich schon völlig unwartbar. Wenn ich irgendwo eine Funktion sehe, die einen Parameter x bekommt, woher soll ich den wissen, was das x ist und was das kann?

    Nimm mal das als Beispiel: https://docs.python.org/3/library/argparse.html vs http://www.boost.org/doc/libs/1_55_0/doc/html/program_options/tutorial.html#idp163291912
    Welcher Code ist lesberer:

    // Declare the supported options.
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("compression", po::value<int>(), "set compression level")
    ;
    
    po::variables_map vm;
    po::store(po::parse_command_line(ac, av, desc), vm);
    po::notify(vm);    
    
    if (vm.count("help")) {
        cout << desc << "\n";
        return 1;
    }
    
    if (vm.count("compression")) {
        cout << "Compression level was set to " 
     << vm["compression"].as<int>() << ".\n";
    } else {
        cout << "Compression level was not set.\n";
    }
    
    import argparse
    
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('integers', metavar='N', type=int, nargs='+',
                       help='an integer for the accumulator')
    parser.add_argument('--sum', dest='accumulate', action='store_const',
                       const=sum, default=max,
                       help='sum the integers (default: find the max)')
    
    args = parser.parse_args()
    print(args.accumulate(args.integers))
    

    (Leider kein passendes Syntax Highlighting hier)

    Ist doch viel besser, wenn man den Typen gleich kennt, dann kann man sich den Typen anschauen und man kann auch sonst nichts falsch machen, weil der Compiler einen dabei unterstützt.

    Benannte Arguments siehst du beim Aufruf, den Typen musst du die jedesmal aufs Neue herausfinden.



  • dinosaur, diese Argumente sind irrelevant. Du wirst mich nicht überzeugen. Ich versuche auch nicht dich überzeugen, wenn du dynamisch typisierte Scriptsprachen magst, bleib dabei.
    Im übrigen find ich den von dir geposteten PHP Code nicht lesbarer. Ich hab jedenfalls überhaupt kein Problem mit dem C++ Code. Und ich hab auch nie von 20 Zeilen Programmen gesprochen, da hätt ich auch kein Problem mit einer Scriptsprache. Ich rede von größeren Programmen mit mehreren hundert tausend oder Millionen Zeilen Code.



  • @dinosaur: Ich kann glaube ich gut nachvollziehen, was du meinst. Als ich Python entdeckt habe, ging mir C++ zunächst erst ziemlich auf den Keks. Als ich dann aber Haskell kennengelernt habe, habe ich bemerkt, dass das, was mich an C++ nervte, seine Ursache gar nicht in der statischen Typisierung hatte.
    Seit dem schaue ich mir alle möglichen unterschiedlichen Sprachen und Paradigmen an. Meine Abneigung gegen C++, übrigens die Sprache, mit der ich am allermeisten Erfahrung habe, hat sich wieder gelegt, und ich benutze das, was ich für das jeweilige Projekt am geeignetsten finde. Falls du den Artikel "What to know before debating type systems" noch nicht kennst, empfehle ich ihn dir hier an dieser Stelle mal. 🙂
    http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html



  • Kellerautomat schrieb:

    Ich denke STL (Person) bringt es auf den Punkt: http://nuwen.net/gcc.html#whynotc

    Stephan T. Lavavey pflegt die Standard Template Library von Visual Studio, er verdient sein Geld damit. Natürlich ist die dann ganz ganz dolle und jeder Entwickler wäre ja blöd diese - und damit C++ - nicht zu benutzen. Man beißt nicht die Hand, die einen füttert (allerdings empfiehlt er auf derselben Seite GCC als Compiler ... ganz schön mutig der Kerl. Aber das hat Herb Sutter ja auch schon mal gemacht. Ich schweife ab.). Die Frage muss lauten: Warum verwendet überhaupt noch irgendjemand C anstatt C++? Eine schnelle why c++ sucks Suchanfrage auf startpage oder einer anderen präferierten Suchmaschine liefert einige kritische Ansichten zu C++:

    Kann man von halten was man will, aber völlig ohne Substanz sind diese Ansichten nunmal nicht. C++ ist eine überladene (hehe) Sprache, die viele viele Fallstricke enthält. Und was sagt Stephan über C?

    (...)The problem with C is that it is so small that it doesn't contain enough support for modern programming techniques. C has insufficient support for object-oriented programming and no support for generic programming.(...)

    Templates fehlen, ja. Diese mit Makros nachzubauen ist keine schöne Lösung, macht denke ich auch kaum einer. Objektorientierte Programmierung ist in C aber nun wirklich nicht schwierig. Ob ich nun

    class A
    {
        public:
            int DoSomething() const;
        private:
            int x;
            int y;
    };
    
    int A::DoSomething() const
    {
        return 4*x + 3*y + 5;
    }
    

    oder

    typedef struct A {
        int x;    // private member
        int y;    // private member
    } A;
    
    int A_DoSomething(const A* this)
    {
        return 4*this->x + 3*this->y + 5;
    }
    

    schreibe, sollte niemanden überfordern. Mehr ist es doch im Grunde nicht. Vererbung? Virtuelle Funktionen? Auch alles kein Problem, muss man halt die vtbl selbst bereitstellen. Auch das überfordert niemanden. Falls doch liegt das Problem nicht bei C.

    (...)For some insane reason, GNU/Linux and most GNU/Linux programs are still written in C. I believe that the underlying reason is lack of vision.(...)

    Ich kann schon eine pulsierende Ader an Linus Torvalds Schläfe sehen. Gleich wechselt er in den Rage-Mode :D. Naja, was ist denn die Alternative zu C im Kernel? Ganz sicher nicht C++, weil man da die ganzen schönen Features wie exceptions und die STL eben nicht verwenden kann, zumindest nicht out-of-the-box. Was bleibt ist die Restriktion auf ein C-ähnliches subset. Kann man auch gleich C für verwenden.

    Anyways, C should not be used in this day and age. C should not be learned. C should not be taught.

    Und wer bringt den coolen Kids von morgen dann bei was Pointer und plain-old C-Strings sind. Die verfallen doch in eine Angststarre wenn die STL mal nicht zur Verfügung steht und sie rohe Zeiger anfassen müssen.


  • Mod

    Bier schrieb:

    Objektorientierte Programmierung ist in C aber nun wirklich nicht schwierig. Ob ich nun

    class A
    {
        public:
            int DoSomething() const;
        private:
            int x;
            int y;
    };
    
    int A::DoSomething() const
    {
        return 4*x + 3*y + 5;
    }
    

    oder

    typedef struct A {
        int x;    // private member
        int y;    // private member
    } A;
    
    int A_DoSomething(const A* this)
    {
        return 4*this->x + 3*this->y + 5;
    }
    

    schreibe, sollte niemanden überfordern. Mehr ist es doch im Grunde nicht. Vererbung? Virtuelle Funktionen? Auch alles kein Problem, muss man halt die vtbl selbst bereitstellen. Auch das überfordert niemanden. Falls doch liegt das Problem nicht bei C.

    Das ist zwar Objektorientierung nach der Lexikondefinition, aber die richtig coolen Sachen, die man damit in C++ und anderen Sprachen machen kann (automatische Konstruktoren und Destruktoren sind so gut!), kann man damit eben nicht machen.
    Und virtuelle Funktionen und Vererbung überfordern die meisten Leute sicherlich schon. Selber vtbl zu schreiben ist schon reichlich viel Aufwand.


Anmelden zum Antworten