Warum hat C++ so eine aufwendige Syntax?
-
Undertaker schrieb:
man kann in C++ mehr falsch machen, z.b. pointer statt referenzen zurückgeben oder eine referenz auf eine lokale variable zurückgeben und schon geht gar nix mehr.
Wieso eigentlich? Kann der Compiler da keine Fehlermeldung ausgeben, wenn man eine Referenz auf eine lokale Variable zurückgibt? Oder gibts wieder einen sonderfall wo es doch irgendwie geht?
-
OK, dann nochmal langsam:
Ja, du mußt einige Dinge beachten, wenn du Operator-Überladung perfekt einsetzen willst. Aber genau die selben Inkonsitenzen tauchen auch auf, wenn man das Problem nicht mit Operatoren, sondern mit "normalen" Methoden angehen will - nur sind da die Ansprüche von Nutzern seltsamerweise deutlich geringer.(wer einen operator+ sieht, geht gleich auf die Suche nach dem zugehörigen operator+=, aber niemand hat ein Problem damit, wenn es zu einer Funktion add() kein entsprechendes add_assign() gibt)
@Holztisch: Die meisten Compiler sind in der Lage, bei sowas zu warnen. Aber bei komplexen Funktionen wird es wohl zu aufwendig, alle Möglichkeiten abzufangen.
-
Tut a.add(b); jetzt eigentlich a verändern? Ich merke mir sowas irgendwie nie

Und ist es nicht irgendwie komisch dass a.add(b) != b.add(a) ist?Wie erstelle ich ein Objekt das einfach nur den wert von a+b hat?
Foo c=a+b;?
ne... geht ja nicht.Foo c=new Foo(a); a.add(b);übersicht ftw?
Foo c=new Foo(); c.add(a).add(b);mhm...
oder hat add() doch nicht a verändert? dann wäre es ja einfach:
Foo c=a.add(b);aber wie addiere ich dann etwas zu a?
a=a.add(b);mhm, das macht dann aber hier autsch:
public void foo(Foo a) { a=a.add(b); }während ein a veränderntes add() hier keine probleme bringen würde...
aber wie gesagt, der Trick mit add() ist immer: ob es das Objekt verändert oder nicht. ganz so einfach ist die sache dann doch nicht.
übrigens soll das nicht heissen dass Java oder add() schlecht ist. sondern einfach dass nicht alles so simpel ist wie es scheint. operatoren haben eigene probleme - aber das liegt nicht in der natur dass sie operatoren sind, sondern in der natur was sie tun. wie man sieht ein add() ist ein kompliziertes kleines ding und schreit nur nach fehlern. genauso wie operatoren nach fehlern schreien.
aber niemand würde versuchen
a+b;auszuführen. ein
a.add(b);dagegen sieht aber gut aus. auch wenn beide das selbe machen.
hat nicht jede art ihre eigenheiten?
-
CStoll schrieb:
Aber genau die selben Inkonsitenzen tauchen auch auf, wenn man das Problem nicht mit Operatoren, sondern mit "normalen" Methoden angehen will - nur sind da die Ansprüche von Nutzern seltsamerweise deutlich geringer.
was leicht verständlich ist, denn überladene operatoren sollen intuitiv anwendbar sein. wenn '+' überladen wurde gehört dazu auch, dass z.b. sowas wie 'a += b + c + d' funktioniert.

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);
-
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
