"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

Nach C kommt D ...

JC 03.01.2007 - 16:25 3152 16
Posts

gue

Addicted
Avatar
Registered: Feb 2003
Location: Linz
Posts: 400
Zitat von Buschmann
In diesem Fall hat der Programmierer versagt. Wie so oft kommt es darauf an wie es eingesetzt wird. typedef std::map < std::string, std::pair < A, B > > ::iterator ABPairIterator wird aus gutem Grund oft verwendet, und verständlich ists wohl, oder? Wenn ein Programmierer eine Instanz einer Rendererklasse nicht "renderer" sondern "apfelbaum" nennt, sind jetzt Objekte schlecht?
Mir wäre es lieber, wenn es voll ausgeschrieben wird.

Zitat
"Freie Funktionen" gibt es in C++ und in D ohnehin nicht wirklich. Die Funktionen, die du meinst, sind halt Teil des globalen Namespace. Und nein, nicht alles macht in Klassen Sinn.
Dann zumindest in einen speziellen Namespace. Wie gesagt finde ich es besser, wenn es spezielle Klassen gibt, in die die Funktionalität gepackt ist, z.B. java.lang.Math; Ansonsten sollte die Funktionalität vom Objekt erfüllt werden (Beispiel str.toLowerCase() statt toLowerCase(str); - das habe ich mit OO-Ansatz gemeint).

Zitat
Offenbar hast du auch von C keine Ahnung, denn dort ist die Standardrepräsentation ein char* Pointer zu einem Array, nicht das Array selbst.
Die Standardrepräsentation von Strings in C ist ein 0-terminiertes Char-Array. Dass Arrays an Bibliotheksfunktionen by-reference (char *) übergeben werden ist wohl klar. Aber bitte, da du ja der C-Gott schlechthin zu sein scheinst und ich davon keine Ahnung habe, bin ich eh schon ruhig :bash:

Zitat
D kann Arrays direkt managen, C kennt Arrays nicht als eigenen Datentyp (der [] operator ist nur ein Index in einen Speicherbereich), daher sind Buffer overflows so leicht und diese einzudämmen so schwer (D weiss über Arraygrößen Bescheid, C logischerweise nicht). Ich hätte mir zwar auch eine echte Stringklasse als Standardrepräsentation gewünscht, aber char[] ist nicht schlecht.
Auch in C könnte die Laufzeitumgebung Buffer-overflows erkennen, wenn [] als Operator auf ein bestimmtes Array behandelt wird. Aufgrund der "Lässigkeit" von C wird das aber nicht gemacht.

Zitat
Das ist reine Geschmackssache. Was ist an [Test] moderner als an unittest Test ?
Unterschied: unittest ist ein Sprachschlüsselwort. Will man nun etwas neues hinzufügen, muss die Sprache und somit der Compiler geändert werden. In Java hatte man das z.B. mit dem transient Schlüsselwort, das mittlerweile durch eine Annotation ersetzt wurde. Annotationen machen natürlich nur mit Reflection einen Sinn (siehe Frys_Assassin's Post).

Buschmann

Bloody Newbie
Registered: Dec 2002
Location: Austria
Posts: 17
Zitat von gue
Zitat von master blue
cool.
du warst beim BH gell :D

Aber NUR dir.

Was ist les -und wartbarer?

Code:
std::map < std::string, std::pair < std::string, SomeStruct > > somemap;

for (std::map < std::string, std::pair < std::string, SomeStruct > > ::iterator it = somemap.begin(); it != somemap.end(); ++it) {
  ....
}

oder

Code:
typedef std::map < std::string, std::pair < std::string, SomeStruct > > SomeStructMap;

SomeStructMap somemap;

for (SomeStructMap::iterator it = somemap.begin(); it != somemap.end(); ++it) {
  ...
}

Nein, ich will solche Würschte NICHT schreiben. Ich nehme typedef. Und nein, das ist kein exotischer Fall, er passiert laufend, wenn man die STL intensiv einsetzt. Daher verwendet man SEHR OFT typedef in C++. Ich hab in meinem Code viele STL-Container, und ohne typedef wäre der Code um Welten unleserlicher. Btw. wird es in C++0x Type Deduction hauptsächlich dafür geben; dann wäre typedef hier unnötig. Also würde es so lauten:

Code:
std::map < std::string, std::pair < std::string, SomeStruct > > somemap;

for (auto it = somemap.begin(); it != somemap.end(); ++it) {
  ...
}

Natürlich, wenn man mehrere Maps/Vektoren/wasauchimmer desselben typs erzeugt, empfiehlt sich auch da ein Typedef.

Zitat
Dann zumindest in einen speziellen Namespace. Wie gesagt finde ich es besser, wenn es spezielle Klassen gibt, in die die Funktionalität gepackt ist, z.B. java.lang.Math; Ansonsten sollte die Funktionalität vom Objekt erfüllt werden (Beispiel str.toLowerCase() statt toLowerCase(str); - das habe ich mit OO-Ansatz gemeint).

Es *gibt* Funktionen, die in keiner strengen Bindung zu einer Klasse existieren (std::find ist ein guter Beispiel dafür). Für solche Funktionen verwendet man auch normalerweise Namespaces. In D schreibst du die Funktionen in Packages, und hast etwas ähnliches.

Im Übrigen will ich wissen, wie du sonst Lambda-Funktionen zusammenbringen willst..

Zitat
Die Standardrepräsentation von Strings in C ist ein 0-terminiertes Char-Array. Dass Arrays an Bibliotheksfunktionen by-reference (char *) übergeben werden ist wohl klar. Aber bitte, da du ja der C-Gott schlechthin zu sein scheinst und ich davon keine Ahnung habe, bin ich eh schon ruhig

Das 0-terminierte Array ist eine Konvention, und wird nicht von der Sprache forciert - genau das ist das Problem. In D hast du Arrays, die auch als solche bekannt sind; in C wissen Stringfunktionen nichts von Arrays, sie kennen nur einen Pointer zu einen Speicherbereich mit einem nullterminierten Array - zumindest nehmen sie an, es ist ein nullterminiertes Array, wenns keiner ist, gibts keine Chance, das rauszufinden (ausser einem Programmabsturz mit nachfolgenden tollen Debugsessions). Der Unterschied liegt in dem Informationsgehalt; wenn eine Funktion *weiss*, was ein Array ist, weiss sie auch über die Arraygrenzen Bescheid. Man kann in C auch einfach bis ins unendliche den char* pointer inkrementieren (passiert tatsächlich wenn es keinen Nullterminator gibt). Deswegen verwendet man in C++ auch std::string und nicht char*, std::vector und keine malloc/realloc-Konstrukte.

Zitat
Auch in C könnte die Laufzeitumgebung Buffer-overflows erkennen, wenn [] als Operator auf ein bestimmtes Array behandelt wird. Aufgrund der "Lässigkeit" von C wird das aber nicht gemacht.

Der [] operator ist in C eine Dereferenzierung eines Pointers mit Offset, mehr nicht. p[1]; ist äquivalent zu *(p + 1); in C++ ist das natürlich anders, weil man DORT (und nicht in C) * und [] überladen kann. []-Checks würden wahrscheinlich eine nicht unerhebliche Menge an C-Code unbrauchbar machen, weil speziell in der Pointerarithmetik sehr viel getrickst wird.

Zitat
Unterschied: unittest ist ein Sprachschlüsselwort. Will man nun etwas neues hinzufügen, muss die Sprache und somit der Compiler geändert werden. In Java hatte man das z.B. mit dem transient Schlüsselwort, das mittlerweile durch eine Annotation ersetzt wurde. Annotationen machen natürlich nur mit Reflection einen Sinn (siehe Frys_Assassin's Post).

Reflection vermisse ich in D tatsächlich. Es ist aber wahrscheinlich eher eine Versäumnis in der Standardbibliothek, da die Sprache selber die nötigen Symboltabellen zu haben scheint. Wenn es drinnen ist, können wir über Annotationen reden.
Bearbeitet von Buschmann am 11.01.2007, 08:41
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz