Warum hat C++ so eine aufwendige Syntax?



  • Undertaker schrieb:

    Shade Of Mine schrieb:

    Tut a.add(b); jetzt eigentlich a verändern? Ich merke mir sowas irgendwie nie 😞

    ich bin für 'nicht verändern'
    wenn man verändern will sollte man schreiben a = a.add(b);

    rein performance-technisch ist += schneller als + (letzteres braucht eine Kopie) - von daher würde ich zu einer (nicht-ändernden) add()-Methode eine (ändernde) add_assign() erwarten. Und damit sind wir wieder bei den unterschiedlichen Ansprüchen - du hast kein Problem damit, 'a=a.add(b);' zu schreiben, aber bei einem operator+ erwartest du sofort, daß es einen dazu passenden operator+= gibt, um 'a=a+b;' abkürzen zu können.

    Aber das hat schon nichts mehr mit der Sprache zu tun, das ist imho lediglich eine Frage der Erwartungshaltung der Nutzer.



  • Also ich würde in Java folgendes bevorzugen:

    Integer a,b,c;
    
    a = add( b, c );
    
    add_to( a, b );
    

    da das nicht geht, würd ich zur Not auch ein

    a = Math.add( b, c );
    
    Math.add_to( a, b );
    

    nehmen.

    Wäre eindeutiger als das a.add(b).



  • kann man da nicht auch sowas machen?

    a.gleich(a.add(b));
    

    nur um sicherzu gehen.



  • Chris++ schrieb:

    kann man da nicht auch sowas machen?

    a.gleich(a.add(b));
    

    nur um sicherzu gehen.

    jetzt machst du dich aber darüber lustig 😉



  • Ich denke "Shade Of Mine" hat es sehr gut auf den Punkt gebracht. Man kann darüber diskutieren, ob "a.add(b)" nun a verändert oder nicht. Man kann aber nicht darüber diskutieren, ob "a + b" a verändert oder nicht.

    Man kann natürlich mit dem operator+ auch erreichen, daß "a + b" a verändert. Dann ist es aber zweifellos ein Designfehler. Bei a.add(b) ist das Geschmackssache und daher weniger gut lesbar und begreifbar. "lolz" hat es ja im Prinzip bewiesen, wenn er sagt "Also ich würde in Java folgendes bevorzugen". Er kann nicht sagen: so ist das einzig richtige, sonder nur, daß ihm das so besser gefällt.

    Operatorüberladung dient dazu, den Code lesbarer zu machen. Die Kritiker dieses Features zeigen immer wieder Beispiele, wo das misbraucht wird, um Code unlesbar zu machen. Richtig angewandt verbessert es aber den Code.

    Natürlich hätte C++ eine einfachere Syntax, wenn es Operatorüberladung nicht gäbe. Auch Java hätte eine einfachere Syntax, wenn es while-Schleifen nicht gäbe. Ich bevorzuge aber eine Sprache, die mir die Ausdrucksmittel zur Verfügung stellt, um meinen Code möglichst intuitiv lesbar macht.



  • Undertaker schrieb:

    Xin schrieb:

    ...aber grundsätzlich muss man C++ als eine der besten Sprachen auf dem Markt akzeptieren.

    weil sie weit verbreitet ist bzw. oft genutzt wird, oder wieso meinst du das?
    🙂

    Wenn Du Dir Stellenangebote ansiehst, so wird Java und C# werden inzwischen deutlich mehr genutzt als C++.

    Ich halte C++ für die leistungsfähigere Sprache, doch gefragt sind inzwischen Sprachen, die bei weniger Erfahrung und Qualifikation schneller Resultate liefern.



  • das mit den selbstgemachten operatoren ist noch nicht mal das schlimmste. sowas z.b:

    class A
    {
        static int x;
    };
    int A::x = 1234;
    

    ist extrem doofe syntax. warum kann man die initialisierung nicht bei der definition mit angeben?
    🙂



  • tntnet schrieb:

    Operatorüberladung dient dazu, den Code lesbarer zu machen. Die Kritiker dieses Features zeigen immer wieder Beispiele, wo das misbraucht wird, um Code unlesbar zu machen. Richtig angewandt verbessert es aber den Code.

    Natürlich hätte C++ eine einfachere Syntax, wenn es Operatorüberladung nicht gäbe. Auch Java hätte eine einfachere Syntax, wenn es while-Schleifen nicht gäbe. Ich bevorzuge aber eine Sprache, die mir die Ausdrucksmittel zur Verfügung stellt, um meinen Code möglichst intuitiv lesbar macht.

    “The very fact that it’s possible to write messy programs in Perl is also what makes it possible to write programs that are cleaner in Perl than they could ever be in a language that attempts to enforce cleanliness” (Larry Wall: Linux World, 1999)

    ... das gilt so sicherlich auch für C++.



  • Undertaker schrieb:

    das mit den selbstgemachten operatoren ist noch nicht mal das schlimmste. sowas z.b:

    class A
    {
        static int x;
    };
    int A::x = 1234;
    

    ist extrem doofe syntax. warum kann man die initialisierung nicht bei der definition mit angeben?
    🙂

    Weil das da oben keine Definition ist 😉 (und das ist keine Definition, um Komplikationen mit der ODR zu vermeiden)



  • CStoll schrieb:

    Weil das da oben keine Definition ist 😉 (und das ist keine Definition, um Komplikationen mit der ODR zu vermeiden)

    aber es hätte doch eine sein können. in 'ähnlichen sprachen' sieht das nicht so merkwürdig aus.



  • Undertaker schrieb:

    CStoll schrieb:

    Weil das da oben keine Definition ist 😉 (und das ist keine Definition, um Komplikationen mit der ODR zu vermeiden)

    aber es hätte doch eine sein können. in 'ähnlichen sprachen' sieht das nicht so merkwürdig aus.

    In diesen ähnlichen Sprachen hast du aber ein anderes Modulsystem. Man darf nunmal nicht vergessen, dass es C++ schon nen paar Jährchen länger gibt als die ganzen Sprachen mit denen man es hier vergleicht. Diese neuen Sprachen konnten bei Ihrer Entwicklung direkt aus den "Fehlern" der älteren Sprachengeneration profitieren.
    Selbst C++ hätte wohl ein richtiges Modulsystem haben können, wenn ein Designziel nicht die C-Kompatibilität gewesen wäre (und ohne der wäre C++ sicherlich nicht so populär geworden).



  • Undertaker schrieb:

    aber es hätte doch eine sein können. in 'ähnlichen sprachen' sieht das nicht so merkwürdig aus.

    Der Grund liegt in der Natur der Sache. Du kannst in C auch nicht in einem Header "int x = 1234;" schreiben, und den Header in mehreren Sourcen inkludieren, da es dann multiple definitions vom Linker geben wird. Das ist die selbe Situation wie hier: Der Compiler muss wissen, wo "A::x" definiert wird, um das Symbol nur einmal zu erzeugen. Benutzen kann man es hingegen sooft man möchte, deshalb muss die Deklaration getrennt vorliegen.

    Also hat hier die Syntax rein technisch gesehen schon eine Berechtigung.



  • kleine Bemerkung schrieb:

    ...
    Daß C++ so komplex ist, liegt unter anderem an zwei Dingen:
    1. Kompatibilität mit C (wurde schon genannt)
    2. Statische Typisierung
    ...

    3. Soll eine Sprache komplexe Möglichkeiten aber nur einen möglichst begrenzten Satz an keywords und syntaktischen Zeichen (obwohl da ja außer ^°§/`´ schon fast alles dabei ist) haben, bleibt einem nicht viel Anderes übrig, als auf Konstruktionen zurückzugreifen.

    Gruß,

    Simon2.



  • Holztisch schrieb:

    CStoll schrieb:

    Wäre es nicht einfacher für die Compilerhersteller auf solche exotischen Sachen zu verzichten und statt dessen mehr Performanceoptimerung zu machen?

    Was hat denn das eine mit dem anderen zu tun?

    Na, ich denk mal das es einfacher ist Code zu optimieren, wenn dieser einfacher ist. Ich kann mir gut vorstellen, dass es Stellen gibt, wo man was nicht oder nur sehr aufwendig optimieren kann, weil es sein kann das etwas zusätzlicheres und komplizierteres beachtet werden muss.

    Willst Du nun eine simplere Syntax (die für den menschen einfacher lesbar ist) oder eine simplere Sprache (also eine, die weniger kann) ?
    Nach dem Parsing spielt die Syntax sowieso keine Rolle mehr und vorher optimiert sowieso kein Compiler. Wenn Du also eine simplere Sprache möchtest, solltest Du mal formulieren, was Dir an C++ unnötig komplex vorkommt. Geschachtelte Funktionsprototypen hast Du schon genannt ... allerdings ist das ein wenig inkonsistent, denn im globalen Namensraum willst/musst Du sie schon noch zulassen und damit hast Du letztlich nichts vereinfacht:

    MyType f(); // soll Funktionsprototyp sein
    
    int main() {
       MyType g(); // soll verboten sein ? Oder ein MyType mit DefCtor-Aufruf ?
    ...
    

    Ehrlich gesagt: Simplere Sprachen gibt's schon zuhauf - ich bin froh, dass C++ da mehr bietet.

    Gruß,

    Simon2.



  • CStoll schrieb:

    PS: Jetzt wurde am Anfang nix von Java erwähnt, aber sobald es einmal gesagt wurde, gibts hier wieder Java vs C++...

    Und das wundert hier noch irgendjemanden?

    vielleicht hilfts wenn gerade du dich mal in solchen threads ab und zu zurückhältst...

    bezüglich des a.add(b) ist eure diskussion so sinnlos wie ein kropf, macht euch erstmal klar was euer a sein soll. eine zahl? eine liste? bei letzterem wäre alles andere außer dass sich a, die liste, natürlich verändert, sinnlos 👎



  • LordJaxom schrieb:

    Der Grund liegt in der Natur der Sache. Du kannst in C auch nicht in einem Header "int x = 1234;" schreiben, und den Header in mehreren Sourcen inkludieren, da es dann multiple definitions vom Linker geben wird.

    in C gibt's ja auch keine klassen und auch keine structs mit statischen membern 😉
    technisch gesehen wäre es doch kein problem. wenn der header von mehreren sources includiert würde (was ja in C++ üblich ist), dann könnte der linker doch erkennen, was 'static int A::x' ist, und dementsprechend nur ein unikat erzeugen.
    🙂

    btw: ich glaube es liegt eher an struppis erstem macro-compiler (CFront), der das nicht konnte und dann musste es so bleiben 😃



  • ein gast schrieb:

    CStoll schrieb:

    PS: Jetzt wurde am Anfang nix von Java erwähnt, aber sobald es einmal gesagt wurde, gibts hier wieder Java vs C++...

    Und das wundert hier noch irgendjemanden?

    vielleicht hilfts wenn gerade du dich mal in solchen threads ab und zu zurückhältst...

    Falls es dir nicht aufgefallen ist, dies ist ein C++ Forum - und wenn da jemand ankommt und "unsere" Sprache schlechtmacht, dann wird die gesamte Stamm-Mannschaft an die Decke gehen (und Java-Nutzer scheinen besonders viel Spaß daran zu empfinden, "uns" zu provozieren :D).

    bezüglich des a.add(b) ist eure diskussion so sinnlos wie ein kropf, macht euch erstmal klar was euer a sein soll. eine zahl? eine liste? bei letzterem wäre alles andere außer dass sich a, die liste, natürlich verändert, sinnlos 👎

    Es geht hier nicht um a.add(b) für sich betrachtet, sondern um den Vergleich von a.add(b) vs. a+b (oder doch eher a+=b?) für eine selbstdefinierte Zahlenklasse - bei Operatoren ist die Bedeutung semantisch gegeben, bei einer Methode mußt du diese Bedeutung selber definieren. Und das ist wohl der Grund, warum Anwender mit Operatoren kritischer umgehen als mit Methoden.

    Undertaker schrieb:

    LordJaxom schrieb:

    Der Grund liegt in der Natur der Sache. Du kannst in C auch nicht in einem Header "int x = 1234;" schreiben, und den Header in mehreren Sourcen inkludieren, da es dann multiple definitions vom Linker geben wird.

    in C gibt's ja auch keine klassen und auch keine structs mit statischen membern 😉
    technisch gesehen wäre es doch kein problem. wenn der header von mehreren sources includiert würde (was ja in C++ üblich ist), dann könnte der linker doch erkennen, was 'static int A::x' ist, und dementsprechend nur ein unikat erzeugen.

    Ja, aber es würde einen Mehraufwand bedeuten für den Compiler, um darüber Buch zu führen - und das stört wieder die angestrebte Abwärtskompatibilität zu C (und gerade zu Zeiten, als C++ entstanden ist, wurden oft noch C-Linker verwendet, die mit solchen Daten nicht zurechtgekommen wären).



  • OK alles an C++ ist super. Zhread closed.



  • CStoll schrieb:

    ...dies ist ein C++ Forum...

    es ist immer noch das C/C++ forum 😉



  • Ende schrieb:

    OK alles an C++ ist super. Zhread closed.

    Nö, aber es ist auch nicht alles an C++ schlecht, wie es einem einige gerne verkaufen wollen.


Anmelden zum Antworten