Programiersprache für Anfänger



  • asdflllsss schrieb:

    Ich schon! Gerade wenn man wenig Erfahrung in C++ hat, muss man sich kaum mit Memory Leaks rumärgern. Die fehleranfälligen Pointer fallen auch weg.

    Definitiv, aber wenn man die Produktivität vergleicht, dann wohl die von "ausgewachsenen" Programmierern. Und ich denke, da wird praktisch gar nicht mehr mit roher Allokierung gearbeitet und falls doch, dann ausreichend gekapselt, so dass man idR keine Speicherlecks mehr hat.



  • Badestrand schrieb:

    Zum einen wohl die große Standardbibliothek, die Suche nach externen Bibliotheken beinahe überflüssig machen soll, zum anderen die bessere Tool- und Deployment-Unterstützung.

    Hem, in real world projects braucht man aber immer eine externe Library. Wir schleppen in unseren Projekten an die 50 MByte externer JARs mit uns rum, weil die Standard-Library halt nur Standard-Klassen bietet, und man am Ende aber Software individuell entwickelt. Also suche ich mir auch meine individuellen Libs raus, egal ob es einfache Dinge wie log4j ist, oder Axis2 für SOAP, oder itext um PDF zu generieren... ich kenne bei uns kein einziges Projekt, das nicht mind. eine externe JAR hinzufügen muß.

    Und bessere Tools... was soll das sein? Es gibt gute Tools, aber wenn man natürlich noch mit VisualC++ 5.0 arbeitet (wie mir letztens ein neuer Kollege erzählt hat, weil er vorher bei SIEMENS ein C++-Projekt hatte), dann soll man auch Java-Tools von Damals als Vergleich nehmen.



  • muemmel schrieb:

    Irgendwie kann ihc mir das nicht so richtig vorstellen. Man kann doch mit C++ auch die Zeiger weglassen und (zumindest vom Aussehen her) fast identisch wie mit Java oder C# programmieren.

    Ja, in der Theorie kannst du mit C++ fast nach jedem Paradigma programmieren. Nur läßt dich der Compiler sehr oft ins offene Messer rennen. Auch die Tatsache, daß solche Paradigmenverbiegungen gewöhnlich mit massivem Einsatz von Templates umgesetzt werden, vereinfacht die Fehlerdiagnose gerade für Anfänger nicht.

    Es kann durchaus von Vorteil sein, wenn gewisse Details nicht als Templates, sondern als Spracheigenschaften umgesetzt werden.
    Beispielsweise referenzzählende Zeiger: stattdessen in der Sprache umgesetzt werden. Wenn du in Java, einer .NET-Sprache (GC) oder Delphi (referenzgezählte Interface-Referenzen) eine Referenz falsch benutzt, sagt der Compiler dir das; in C++ landest du mit einer Fehlermeldung, die mit dem tatsächlichen Problem möglicherweise nichts zu tun hat, in der Template-Deklaration.

    Auch beim Debuggen sind Smart-Pointer ein Krampf. Jeder Step-into auf einer Zeile, in der ein Smart-Pointer benutzt wird, führt dich in den überladenen Operator -> o.ä.



  • asdflllsss schrieb:

    Ich schon! Gerade wenn man wenig Erfahrung in C++ hat, muss man sich kaum mit Memory Leaks rumärgern. Die fehleranfälligen Pointer fallen auch weg.

    Wenn man Sprachen direkt vergleicht, sollte man von gleichen Wissensstand ausgehen. Wenn man einigermaßen erfahren in den entsprechenden Sprachen ist, greift dein Argument nur bedingt.

    Und was "fehleranfälligen Pointer" angeht: Die Häufigsten Fehlermeldungen die ich aus C#/Java kenne sind die Null-Pointer Exceptions. Da man dort sehr wohl mit Zeigern arbeitet (Ja, gewisse Fallstricke werden durch eine Referenzsyntax vermieden, aber im Gegenzug eine höhere Sicherheit vorgegaukelt). Und mir ist egal ob diese dann Null-Referenz oder wie auch immer genannt wird.

    Das heißt jetzt aber nicht, das Speicherverwaltung garnicht ins Gewicht fällt.

    muemmel schrieb:

    Ich lese hier immer, daß Programmentwicklung mit C# oder Java so viel schneller gehen soll als mit C++.
    Irgendwie kann ihc mir das nicht so richtig vorstellen.

    Da ich in den Sprachen C++/Java/C# meine Erfahrungen habe, meine Meinung (begrenze mich aber aufgrund der aktuelleren C++/C# Kenntnisse auf diese beiden im Vergleich):

    1. Framework
    In C# ist das mitgelieferte Framework umfassender und weitgehend auch leichter zu bedienen als alles, was ich von C++ kenne. Zudem ist der Stil in .Net recht einheitlich, in C++ muss man häufig für den gleichen Umfang mehrere Bibliotheken mit unterschiedlichen Stil verwenden (Auch diese Stilunterschiede kosten Zeit).

    2. Die IDE-Unterstützung
    a) Allgemein
    Ich würde sagen im Grundsatz sind moderne IDEs in allen Sprachen durchaus mächtig. Die Unterstützung wird aber auch durch Fähigkeiten der Sprache besser...
    b) Unterstützung dank Reflektion
    Was in C++ viel Analyseaufwand bei der Toolunterstützung kostet, bekommt man in Sprachen mit Reflektion teilweise fast geschenkt. Codevervollständigungen etc. die ja durchaus auch die Arbeit beschleunigen können, lassen sich leichter implementieren, was auch die Verbreitung ebensolcher Bestandteile erhöht.
    c) Bibliotheksunterstützung
    Zumeist hat man auch eine bessere Unterstützung der Bibliotheken, weil man selten externe Bibliotheken braucht. Häufig reicht in C# und Java bereits das mitgelieferte aus, wodurch die Dokumentation, die direkte IDE-Unterstützung, Grafikdesigner etc. eher zum Standard gehören als in C++.

    3. Beschleunigung dank Codereduzierung und Vereinfachungen
    Wenn ich ein und das selbe in C++ sowie C# umsetzen will, stelle ich zumindestens fest, das ich in C# meist weniger Code für die gleiche Funktionalität brauche. Es gibt hier auch Ausnahmen, aber über das Projekt gesehen gehe ich - je nach Art des Projektes - von einer Einsparung von mindestens 25% und mehr.
    Um so komplexer das Projekt ist - Grafik, Mehrschichtenarchitektur, etc., um so höher ist der Codeunterschied nach meiner Erfahrung.
    Das liegt zum Teil aber auch daran, das vieles vereinfacht dargestellt wird, weniger Sonderfälle (dafür natürlich auch einige "Stellschrauben" weniger) existieren.

    Man erkäuft sich natürlich auch Nachteile mit Java/C#. Java/C#-Programme in gleichen Funktionsumfang wie C++ Programme haben in den überwiegenden Fällen, mit den ich konfrontiert wurde, weniger Performance, höhere Speicheranforderungen, längere Startzeiten... Dies heißt aber nicht das alle Java/C#-Programme automatisch langsam sind, wobei im direkten Vergleich (zumindestens bei Standardsoftware die ich kenne), das native Programm den Vorsprung hat.

    cu André



  • asc schrieb:

    Zudem ist der Stil in .Net recht einheitlich, in C++ muss man häufig für den gleichen Umfang mehrere Bibliotheken mit unterschiedlichen Stil verwenden (Auch diese Stilunterschiede kosten Zeit).

    Nicht zu knapp.

    Vermutlich ist das eines der größten Defizite dieser Sprache: eine stilistische und architektonische Basis, wie sie in Java, C# oder Delphi allgemein anerkannt ist, existierte für C++ nie. Beispielsweise gibt es in jeder halbwegs produktiven Umgebung mehrere String-Typen, unter anderem, weil std::string ein evasiver Minimalismus von einer Stringklasse ist. Und auch sonst sind die Unausgegorenheiten von Standard-C++ kaum zu zählen: es gibt in der Standardbibliothek keine tauglichen Smart-Pointer, keine taugliche String-Formatierungsfunktion, es gibt kein klar trennendes Modulkonzept, keine einheitliche Implementation von Delegaten, nur die mehr als minimalistische RTTI, etc. pp.

    Die unvermeidliche Folge: unzählige Individuallösungen, sämtlich inkompatibel.



  • asc schrieb:

    Und was "fehleranfälligen Pointer" angeht: Die Häufigsten Fehlermeldungen die ich aus C#/Java kenne sind die Null-Pointer Exceptions. Da man dort sehr wohl mit Zeigern arbeitet (Ja, gewisse Fallstricke werden durch eine Referenzsyntax vermieden, aber im Gegenzug eine höhere Sicherheit vorgegaukelt). Und mir ist egal ob diese dann Null-Referenz oder wie auch immer genannt wird.

    Wenn man in C++ einen Nullpointer (oder Zeiger ins Nirvana) derefenziert, bekommt man eine Schutzverletzung, Segmentation Fault, Core Dump, was auch immer (jedenfalls war das so, als ich mich noch damit beschäftigen durfte).

    In Sprachen mit Managed Code kann ich solche Fehler auffangen und behandeln. Ich kann ein Fehlerreport generieren, wo drin steht, welche Variable in welcher Methode welcher Klasse (mit Zeilennummer) null war. Den Report kann man dann zusammen mit einem Screenshot der Anwendung, den letzten 100 Zeilen des Logfiles und einem Kommentar des Anwenders an den Support schicken und sofort mit dem Bugfixing anfangen. Ein enormer Vorteil.
    Von den Möglichkeiten des (Remote-)Debugging mit Hot-Code-Replacement ganz zu schweigen.

    Bezogen auf Java: Vorteilhaft ist auch das Angebot an Applicationservern (Tomcat, JBoss, etc) und unterstützenden Frameworks (Spring, Hibernate).



  • tfa schrieb:

    In Sprachen mit Managed Code kann ich solche Fehler auffangen und behandeln. Ich kann ein Fehlerreport generieren, wo drin steht, welche Variable in welcher Methode welcher Klasse (mit Zeilennummer) null war.

    das kann man auch mit sprachen die nativen code erzeugen :xmas1:



  • tfa schrieb:

    Wenn man in C++ einen Nullpointer (oder Zeiger ins Nirvana) derefenziert, bekommt man eine Schutzverletzung, Segmentation Fault, Core Dump, was auch immer (jedenfalls war das so, als ich mich noch damit beschäftigen durfte).

    Wie auch schon von sothis_ erwähnt, muss das nicht sein.
    Ich habe, als ich noch mit einen Compiler gearbeitet habe der so gut wie von keiner Bibliothek mehr unterstützt wurde, Smartpointern selbst geschrieben. Und diese hatten, die auch von Java und C# üblichen NULL-Prüfungen, sowie das Exceptionhandling eingebaut.

    Es kommt immer darauf an wie man C++ verwendet, und was man für Zielsetzungen hat.

    tfa schrieb:

    In Sprachen mit Managed Code kann ich solche Fehler auffangen und behandeln.

    Besser ist es, wenn man von vorne herein auch die Exception ausschließen kann. Und NULL-Prüfungen kann man auch in C++ machen.

    tfa schrieb:

    Bezogen auf Java: Vorteilhaft ist auch das Angebot an ... unterstützenden Frameworks (Spring, Hibernate).

    Das kann wieder genau ein Nachteil sein. Sicher, das Angebot von kompatiblen Bibliotheken/Frameworks ist ein Vorteil, aber gleichzeitig auch ein Nachteil (unterschiedliche Stile etc.). Dies ist beispielsweise unter C++ ein großer Vor-/Nachteil: Die extreme Anzahl unterschiedlicher.

    cu André



  • asc schrieb:

    Und was "fehleranfälligen Pointer" angeht: Die Häufigsten Fehlermeldungen die ich aus C#/Java kenne sind die Null-Pointer Exceptions. Da man dort sehr wohl mit Zeigern arbeitet (Ja, gewisse Fallstricke werden durch eine Referenzsyntax vermieden, aber im Gegenzug eine höhere Sicherheit vorgegaukelt). Und mir ist egal ob diese dann Null-Referenz oder wie auch immer genannt wird.

    Naja ok, Du musst ein neues Objekt mit new anlegen, schön. Viel mehr gibt es nicht zu tun. Die Garbage Collection kümmert sich um den Rest.



  • asdflllsss schrieb:

    Naja ok, Du musst ein neues Objekt mit new anlegen, schön. Viel mehr gibt es nicht zu tun. Die Garbage Collection kümmert sich um den Rest.

    Unter C++ doch genauso, nur dass du nicht mit new/delete arbeitest, sondern mit schlauen Zeigern und Containern. Einmal angelegt, RAII besorgt den Rest.



  • sothis_ schrieb:

    tfa schrieb:

    In Sprachen mit Managed Code kann ich solche Fehler auffangen und behandeln. Ich kann ein Fehlerreport generieren, wo drin steht, welche Variable in welcher Methode welcher Klasse (mit Zeilennummer) null war.

    das kann man auch mit sprachen die nativen code erzeugen

    naja, null-pointer schon, aber wenn der pointer sonstwohin zeigt, läuft dein code seltsam anders und du wunderst dich. in sprachen mit managed code gibts nur zwei fälle: entweder es geht, oder es crashed. aber niemals zerbröselt es daten an anderen stellen.
    🙂



  • Badestrand schrieb:

    Unter C++ doch genauso, nur dass du nicht mit new/delete arbeitest, sondern mit schlauen Zeigern und Containern. Einmal angelegt, RAII besorgt den Rest.

    Wenn es nur Smart-Pointer gäbe, wäre das ja ok. Aber man hat immer wieder mit alten oder externen Code zu tun, in dem eben nicht alles mit Smart-Pointern realisiert ist.



  • Bei altem Code hat man aber leider nicht die Wahl der Programmiersprache. Ein Vergleich C++ vs. Java ist nur für neue Projekte sinnvoll.



  • asdflllsss schrieb:

    Badestrand schrieb:

    Unter C++ doch genauso, nur dass du nicht mit new/delete arbeitest, sondern mit schlauen Zeigern und Containern. Einmal angelegt, RAII besorgt den Rest.

    Wenn es nur Smart-Pointer gäbe, wäre das ja ok. Aber man hat immer wieder mit alten oder externen Code zu tun, in dem eben nicht alles mit Smart-Pointern realisiert ist.

    Ahja, weil eine Sprache den Anwender die Verantwortung abnimmt, ist sie automatisch besser? Und seit wann gibt es bitte schön C++ und seit wann Java und Co? Das Konzept der Smartpointer ist schon alt genug um Anwendungen komplett damit zu pflastern.

    Warum macht man dies nicht?
    a) Unwissen
    b) Performanceabwegungen (Manchmal weiß man das bestimmte Fälle nicht eintreten können - Hardwarefehler mal ausgeschlossen)
    ...

    Was ich an C++ gut finde ist gerade die Möglichkeit zu wählen. Das dies dem Programmierer eine höhere Verantwortung auferlegt, ist klar. Zudem gibt es viele Fälle in denen man mit Referenzen arbeiten kann (und in C++ sind diese immer ungleich 0, wenn man nicht mit brachialer Gewalt dort etwas umbiegt).

    cu André



  • asc schrieb:

    Warum macht man dies nicht?
    a) Unwissen
    b) Performanceabwegungen (Manchmal weiß man das bestimmte Fälle nicht eintreten können - Hardwarefehler mal ausgeschlossen)
    ...

    c) Weil die Sprache es nicht forciert.
    d) Weil es nicht die naheliegendste Lösung ist. Welcher Anfänger lädt sich Boost herunter, installiert es und hantiert dann mit std::tr1::shared_ptr <Objekt> herum, wenn man doch einfach Objekt* schreiben kann?

    asc schrieb:

    Was ich an C++ gut finde ist gerade die Möglichkeit zu wählen. Das dies dem Programmierer eine höhere Verantwortung auferlegt, ist klar.

    Mit anderen Worten, ein verpflichtender Intelligenztest für angehende C++-Programmierer wäre vielleicht erwägenswert 😃



  • audacia schrieb:

    ...Weil es nicht die naheliegendste Lösung ist. Welcher Anfänger lädt sich Boost herunter, installiert es und hantiert dann mit std::tr1::shared_ptr <Objekt> herum, wenn man doch einfach Objekt* schreiben kann?...

    Sprechen wir jetzt von "Anwendungen" oder von Anfängern? Zumal ich annehme das std::tr1::shared_ptr tatsächlich in nicht mehr allzu weiter Zukunft auch seinen Buch in Grundlagenbücher findet (Mit C++0x). Ganz davon abgesehen das aktuelle Kompiler den TR1 teilweise mitbringen.

    audacia schrieb:

    Mit anderen Worten, ein verpflichtender Intelligenztest für angehende C++-Programmierer wäre vielleicht erwägenswert 😃

    Böse Gesprochen: Eine gewisse Intelligenz sollte man für die Verwendung in einer x-beliebigen Programmiersprache mitbringen. Den was der Anfänger in C++ falsch macht, das rächt sich auch in C#/Java, wenn gleich dort ggf. mit Exception.



  • Der TR1 und somit shared_ptr & Co. werden heute in jedem aktuellen und vernünftigen C++-Buch behandelt (z.B. in denen von Scot Meyers). Manche Anfängerbücher gehen neben TR1 sogar schon teilweise auf C++0x ein (wie das von Ulrich Breymann). Wer also heute mit C++ anfängt, bekommt Smartpointer gleich mit beigebracht.

    Und Boost muß man heute bei den aktuellen Mature-Compiler auch nicht mehr runter laden, um TR1 nutzen zu können. Der aktuelle GCC hats drin, der MinGW 4.3 (den ich hier parallel mit benutze) hat auch TR1 drin. Und wer MSVS2008 hat, bekommt den TR1 mit dem kostenlosen Feature Pack Upgrade von MS auch noch mit dazu! Und MS hat genug Blogs, Videos (auf channel9) und MSVS-Startseite über TR1... da bekommts auch der letzte mit.

    Wer da noch ne Ausrede hat, das er irgendwie TR1 und Smartpointer verpasst hat, der verpasst auch alles andere und hat somit ein anderes grundsätzliches Problem.



  • Wenn Performance das ABSOLUT wichtigste ist, dann nimmt man noch immer pure Zeiger.



  • asdflllsss schrieb:

    Naja ok, Du musst ein neues Objekt mit new anlegen, schön. Viel mehr gibt es nicht zu tun. Die Garbage Collection kümmert sich um den Rest.

    Ganz so einfach ist es nicht. Speicherlecks sind auch in Java möglich. Der Entwickler muss schon dafür sorgen, dass nicht mehr benötigte Objekte nicht mehr referenziert werden (oder weak references benutzen).

    Badestrand schrieb:

    Unter C++ doch genauso, nur dass du nicht mit new/delete arbeitest, sondern mit schlauen Zeigern und Containern. Einmal angelegt, RAII besorgt den Rest.

    Wenn ich das richtig verstanden habe, funktioniert dieses Konzept nur im Scope der entsprechenden Variable. Was passiert, wenn ich ein Objekt anlege und es in z.B. eine Liste/Hashtabelle o.ä. einfüge und erst Stunden später wieder lösche? Das ist doch dann auch Handarbeit. Ein GC ist da schon mächtiger.



  • HansiHinterseher schrieb:

    Der TR1 und somit shared_ptr & Co. werden heute in jedem aktuellen und vernünftigen C++-Buch behandelt (z.B. in denen von Scot Meyers). Manche Anfängerbücher gehen neben TR1 sogar schon teilweise auf C++0x ein (wie das von Ulrich Breymann). Wer also heute mit C++ anfängt, bekommt Smartpointer gleich mit beigebracht.

    Soweit die idealisierte Theorie. Für die Praxis sieh dir bitte das C++-Subforum an.


Anmelden zum Antworten