Typlose Zeiger in C++



  • Tachyon schrieb:

    Wenn ich mir den Eröffnungspost nochmal durchlese, hast Du vermutlich sogar recht. Ich habe mir meine Vermutung irgendwie aus der Antwort auf Deinen Vorschlag zusammengereimt.

    Ja das mit dem new hab ich nichtmal ansatzweise kapiert was er will 😕



  • Der gewünschte Benutzerna schrieb:

    Kann man nun void *zeiger dazu benützen nacheinander mit dem gleichen Zeiger unterschiedliche formatierungen anzusprechen, die die gleiche Länge haben?

    Ohje, das ist totaler Nonsense. Man kann das technisch zwar machen, aber das ganze ist nicht mehr portabel, da hier solche Dinge wie Padding, Aligment, Byte Order etc. zum Tragen kommen. Wenn man Assembler programmiert, kann man das so machen, da der Code ohnehin nicht portabel ist, sobald man aber mit C++ anfängt muß man davon die Finger lassen.



  • Mich würde mal interessieren, was überhaupt mit dem Wort "Formatierung" in diesem Zusammenhang gemeint ist.



  • ~john schrieb:

    Ohje, das ist totaler Nonsense. Man kann das technisch zwar machen, aber das ganze ist nicht mehr portabel, da hier solche Dinge wie Padding, Aligment, Byte Order etc. zum Tragen kommen. Wenn man Assembler programmiert, kann man das so machen, da der Code ohnehin nicht portabel ist, sobald man aber mit C++ anfängt muß man davon die Finger lassen.

    Das ist ebenfalls Nonsense. Nicht jedes C++ Programm ist dafür gedacht, portabel zu sein. Manchmal will man auch einfach nur schnell zu einer effizienten, günstigen Lösung kommen. Portabel sind C++-Programme schon dann nicht mehr, wenn sie plattformspezifische Bibliotheken benutzen, und das machen eine Menge Programme...



  • asc schrieb:

    Dies sind Dinge die schon darauf hinweisen, das du eher C als C++ entwickelst (unter C++ ist die schreibweise "typedef struct" mehr als unüblich, dies ist eher ein typisches C-Relikt; C-Arrays sind - wie der Name schon sagt auch eher in C als in C++ zu finden). Auch deine Typbeschreibung deutet eher von einer Assemblersichtweise hin.

    Also asc Ich hätte dann auch schon gerne, daß du die C Thematik dann auch für C++ angibst (wie man es in C++ richtig macht).
    Ich benötige einen Typnamen (z.B. für new), jedoch keinen Klassennamen außer für meine dynamische Typen. Wenn gcc es halt nicht anders akzeptiert musst du mir einen Vorschlag machen - ich probiere das gerne aus.

    -----
    Zu dir Shade Of Mine, das unterschiedliche formatieren eines Speicherbereiches lassen wir mal beiseite, wird sonst zu kompliziert hier auf zwei Probleme einzugehen. Das eigentliche Problem ist also die Datenbankklasse mit den normalen Members, die man so braucht, read, write, und und das einstreamen unterschiedlicher Typen (Längen von 10 Byte bis 10 MB pro Typ).
    Ich kann jetzt für jede Datenbank eine eigene Klasse schreiben (ca. 50 Stück) oder eine Klasse für alle Datenbanken. Daraus ergibt sich die Problematik der unterschiedlichen Typen. Das hat dazu gefhürt die Möglichkeit hier zu erörtern, ob dies ohne gröpßeren Aufwand möglich ist. Eine und für mich die plausibelste Mölichkeit ist, den Basiszeiger eines zusammenhängenden Speicherbereiches zu übergeben und die dazugehöige Länge, ist ja oben schon beschrieben. Manche Typen müssen mehrfach in Stücken eingelesen werden, da diese Datenbanken aus dynamischen Datensätzen bestehen.Wir können hier nur abstrakt erörtern, das muss ich auch beim programieren so machen.

    Und ich muss hier auch sagen, daß man C++ nicht programieren kann ohne zu wissen wie der Kompiler funktioniert. Man muss genau wissen wie werden Daten im Speicher abgelegt, was macht new und wie verhält sich was wenn man es so programmiert; da kommt mir meine Assembler Erfahrung teilweise schon zugute.

    Und was Assembler angeht muss ich hier auch noch was loßwerden, Ich programiere mit Assembler jetzt schon seit ca 15 Jahren Opjekt Orientiert und solche Sachen wie X11 oder QT sind nichts besonderes in Assembler und durchaus einfacher zu programieren als mit C++. Sowas wie X11 und QT in Einem habe ich schon in Assembler programmiert - das waren noch Zeiten unter DOS ...
    ------

    Tachyon schrieb:

    So wie ich das verstanden habe, hat er Typen, welche u.a. Zeiger auf andere Typen enthalten. Den Zeigern kann dann bei Bedarf allokierter Speicher (auf die anderen Typen) zugeordnet werden.

    Keine Zeiger, aber der Datensatz ermöglicht es mit seiner enthaltenen Info ihn zu vervollständigen (man kann mit dem ersten Teil den noch fehlenden Teil ausrechnen). Jetzt ist es so, daß mich zwei nicht zusammenhängende Blöcke aber nicht stören, da diese Typen sowieso dynamisch sind und auf zweimal eingelesen werden müssen. Was placement angeht - ja, deshalp wird ein ARRAY von Typen mit new erzeugt - dann ist es automatisch zusammenhägnend.(mit new erzeugte arrays und strings sind immer zusammenhängend)

    2.) Mit Assembler kann ich halt den kompletten dynamischen Datensatz auf einmal einlesen und c++ die nötige Info dazu liefern (Laufzeitimplementierung).

    ducktyping betrift die Umformatierung was ich vorerst hier mal weglassen will.
    ------

    Shade Of Mine schrieb:

    Ja das mit dem new hab ich nichtmal ansatzweise kapiert was er will 😕

    Was braucht ihr da für Info? - Wenn es in diesem Block nicht stehen sollte.

    Wie sieht es nun mit void *zeiger aus? Ist der Geltungsbereich dann nur innerhalb der Funktion, in der ich diesen void *zeiger benutze? Oder überträgt sich das auf die nächsten Aufrufe? Jeder Aufruf der Funktion ist ja mit einem Zeiger auf einen Typ, der eine Länge hat, die sich von der des vorherigen Aufrufs unterscheidet. Ich vermute mal, daß der Geltungspereich die Funktion ist und somit void *auf_gleiche_laenge nur innerhalb der Funktion gilt.



  • Decimad schrieb:

    Mich würde mal interessieren, was überhaupt mit dem Wort "Formatierung" in diesem Zusammenhang gemeint ist.

    Ich denke schon, daß dies ein kompakter Ausdruck ist, der angemessen ist.
    - Wenn 2 Typen gleicher Länge (z.B Typ1 mit 8 chars und Typ2 mit 2 ints) die gleiche Basisadresse haben. Der Seicherbereich ab Basisadresse hat somit 2 unterschiedliche ansprechbare Formate oder anders ausgedrückt: ein Typ formatiert lediglich einen Abschnit im Speicher ab Basisadresse. Speicher ist Speicher und besteht aus Bits erst eine Formatierung sagt mir wie ich einen Speicherbereich benützen soll, muss, darf - so will es C++.



  • ~john schrieb:

    Ohje, das ist totaler Nonsense. Man kann das technisch zwar machen, aber das ganze ist nicht mehr portabel, da hier solche Dinge wie Padding, Aligment, Byte Order etc. zum Tragen kommen. Wenn man Assembler programmiert, kann man das so machen, da der Code ohnehin nicht portabel ist, sobald man aber mit C++ anfängt muß man davon die Finger lassen.

    Da hast du absolut Recht, jetzt muss ich abwegen ....

    IA64 - O.K. davon gehe ich aus.
    Apple hat jetzt IA86 - O.K.
    Sparc - Nein, das ist nicht gut
    S390 - Nein, garnicht gut

    In 2 Jahren hab ich vielleicht die erste Version dann gibt es vieleicht schon einen IA64 64 core dann läuft das Programm auch ordentlich.
    O.K. ich verzichte auf Portabilität.



  • bastl schrieb:

    asc schrieb:

    Dies sind Dinge die schon darauf hinweisen, das du eher C als C++ entwickelst (unter C++ ist die schreibweise "typedef struct" mehr als unüblich, dies ist eher ein typisches C-Relikt; C-Arrays sind - wie der Name schon sagt auch eher in C als in C++ zu finden). Auch deine Typbeschreibung deutet eher von einer Assemblersichtweise hin.

    Also asc Ich hätte dann auch schon gerne, daß du die C Thematik dann auch für C++ angibst (wie man es in C++ richtig macht).

    1. typedef struct ist redundant. Jede struct, class, enum, union ist bereits eine Typdefinition. Das typedef lässt man daher weg. Nachfolgender Code definiert einen Typ xtyp:

    struct xtyp { int x; };
    

    bastl schrieb:

    Ich benötige einen Typnamen (z.B. für new), jedoch keinen Klassennamen außer für meine dynamische Typen

    Keine Ahnung was du damit meinst (Ein Klassenname IST ein Typenname).

    2. Unter C++ verwendet man C-Array eher selten, da es weder sinnvoll Kopiert etc. Statt dessen sind eigentlich die Containerklassen der Standardbibliothek in Verwendung (std::vector, std::list, std::map, std::tr1::array...).

    3. void* ist nicht für delete geeignet. delete benötigt Typinformationen, die erhält es durch ein void* nicht. Wenn du unbedingt mit rohen Speicher hantieren willst, würde ich eher ein char* oder std::vector<char> nehmen, dann kannst du es wenigstens byteweise interpretieren.

    Ebenso kann man void* nur benutzen wenn man weiß wie man die Daten zu interpretieren hat.

    C++ arbeitet nun einmal mit einem statischen Typsystem.

    bastl schrieb:

    Und ich muss hier auch sagen, daß man C++ nicht programieren kann ohne zu wissen wie der Kompiler funktioniert. Man muss genau wissen wie werden Daten im Speicher abgelegt, was macht new und wie verhält sich was wenn man es so programmiert

    Das ist absoluter Nonsense, es sei vielleicht, man will alles auf binärer Ebene bearbeiten, was eigentlich in C++ nicht üblich ist - Dann sollte man gleich in Assembler weiterarbeiten.

    Eine Programmiersprache ist ein Werkzeug um eine Aufgabe zu erledigen. Das man ungefähre Vorstellung hat, wie etwas realisiert werden könnte kann manchmal hilfreich, nicht selten aber auch die sprichwörtlichen Scheuklappen sein. Um ein Ziel zu erreichen sollte es - zumindestens in einer Hochsprache - vollkommen egal sein was der Compiler im Hintergrund daraus macht.

    bastl schrieb:

    Was placement angeht - ja, deshalp wird ein ARRAY von Typen mit new erzeugt - dann ist es automatisch zusammenhägnend.(mit new erzeugte arrays und strings sind immer zusammenhängend)

    Das ist auch beim std::vector oder std::tr1::array definiert.

    cu André



  • Tachyon schrieb:

    Das ist ebenfalls Nonsense. Nicht jedes C++ Programm ist dafür gedacht, portabel zu sein. Manchmal will man auch einfach nur schnell zu einer effizienten, günstigen Lösung kommen. Portabel sind C++-Programme schon dann nicht mehr, wenn sie plattformspezifische Bibliotheken benutzen, und das machen eine Menge Programme...

    Das ist totaler Quatsch! (Wohl bisher nur unter Windows gearbeitet?) UNIX Programme verwenden seit Jahrzehnten spezielle UNIX Libraries und laufen trotzdem auf sehr vielen verschiedenen Prozessorachitekturen.

    Wenn man unter UNIX, Linux oder Windows entwickelt, dann gibt es mehr als eine Prozessorarchitektur! Bei Windows gibt es IA32, IA32-64, IA64 bei den anderen Plattformen kommen noch Power, HP-PA, SPARC, ARM, MIPS etc. dazu. Wenn man da ohne Not von einer spezifischen Anordnung der Daten ausgeht, baut man einfach nur Mist. Zum Beispiel sollen Daten ja auch unabhängig vom 32Bit oder 64Bit Modus eingelesen werden können, und es gibt Betriebssysteme die laufen nicht nur auf einer Hardwarearchitektur. Wenn man nicht gerade an Computerspielen oder ähnlich zeitkritischen Programmen arbeitet sollte man die Finger von Mikrooptimierungen lassen, denn in der Regel lebt der Code länger als einem beim Entwerfen bewußt ist.



  • bastl schrieb:

    IA64 - O.K. davon gehe ich aus.
    Apple hat jetzt IA86 - O.K.
    Sparc - Nein, das ist nicht gut
    S390 - Nein, garnicht gut

    In 2 Jahren hab ich vielleicht die erste Version dann gibt es vieleicht schon einen IA64 64 core dann läuft das Programm auch ordentlich.
    O.K. ich verzichte auf Portabilität.

    1. Du meinst IA32-64. IA64 wäre der Itanium! Windows läuft auf IA64.
    2. Es ist auch über verschiedene Compilerversionen nicht portabel!



  • ~john schrieb:

    Das ist totaler Quatsch! (Wohl bisher nur unter Windows gearbeitet?) UNIX Programme verwenden seit Jahrzehnten spezielle UNIX Libraries und laufen trotzdem auf sehr vielen verschiedenen Prozessorachitekturen.

    Es gibt Ausnahmen, die Regel (zumindestens in der Anwendungsentwicklung in kommerziell orientierten Projekten), ist es möglichst schnell eine Lösung zu präsentieren. Und dazu greifen viele Firmen auf OS-Spezifische Bibliotheken zu.

    Man kann C++ auch sehr portabel schreiben (das es unter vielen Betriebssystemen wieder gelinkt werden kann), aber das erlebe ich eigentlich eher selten. Auch wenn ich selbst ein Fan davon bin in Anwendungen zumindestens die Schichten zwischen UI auf der einen, und Datenzugriff auf der anderen Seite weitgehend portabel zu halten.

    cu André



  • bastl schrieb:

    Ich benötige einen Typnamen (z.B. für new), jedoch keinen Klassennamen außer für meine dynamische Typen.

    "struct" und "class" sind in C++ fast dasselbe. Es sind auch Typen, aber es gibt weitere Arten von Typen.

    bastl schrieb:

    Zu dir Shade Of Mine, das unterschiedliche formatieren eines Speicherbereiches lassen wir mal beiseite, wird sonst zu kompliziert hier auf zwei Probleme einzugehen. Das eigentliche Problem ist also die Datenbankklasse mit den normalen Members, die man so braucht, read, write, und und das einstreamen unterschiedlicher Typen (Längen von 10 Byte bis 10 MB pro Typ).

    Was willst Du machen? Objektgraphen (de)serialisieren oder RDBMS Abfragen auf ein RDBMS loslassen? Davon hängt maßgeblich ab, wie man es umsetzt.



  • bastl schrieb:

    Ich benötige einen Typnamen (z.B. für new), jedoch keinen Klassennamen außer für meine dynamische Typen. Wenn gcc es halt nicht anders akzeptiert musst du mir einen Vorschlag machen - ich probiere das gerne aus.

    Ich glaube ich habe verstanden was du machen willst.
    Aber eine schoene Erklaerung waere nicht schlecht - da muss man nicht soviel raten.

    Du kannst rohen Speicher besorgen:

    void* p = ::operator new(100);
    

    das besorgt die 100 byte Speicher.

    Nun kannst du wenn du zB eine struct Foo oder Bar hast:

    struct Foo { int i[5]; }
    struct Bar { double d[5]; }
    

    Theoretisch ein:

    Foo* f = static_cast<Foo*>(p);
    Bar* b = static_cast<Bar*>(p);
    

    machen - oder aber mit einer Union arbeiten.

    Aber das ist mit sehr grosser Wahrscheinlichkeit genau das falsche vorgehen...

    Das eigentliche Problem ist also die Datenbankklasse mit den normalen Members, die man so braucht, read, write, und und das einstreamen unterschiedlicher Typen (Längen von 10 Byte bis 10 MB pro Typ).
    Ich kann jetzt für jede Datenbank eine eigene Klasse schreiben (ca. 50 Stück) oder eine Klasse für alle Datenbanken.

    Meinst du wirklich 50 unterschiedliche Datenbanken? Oder meinst du 50 unterschiedliche typen?

    Jedenfalls:
    Wenn du Datenbanken meinst - da verwendet man ein vereinheitlichtes interface (zB ODBC, ADO,...) um auf sie zuzugreifen und muss nur gegebenenfalls leicht adaptieren.
    Wenn du Typen meinst: ja, dann musst du 50+ Klassen schreiben, wobei die meisten klassen sehr sehr sehr klein sein werden.

    Daraus ergibt sich die Problematik der unterschiedlichen Typen. Das hat dazu gefhürt die Möglichkeit hier zu erörtern, ob dies ohne gröpßeren Aufwand möglich ist. Eine und für mich die plausibelste Mölichkeit ist, den Basiszeiger eines zusammenhängenden Speicherbereiches zu übergeben und die dazugehöige Länge, ist ja oben schon beschrieben. Manche Typen müssen mehrfach in Stücken eingelesen werden, da diese Datenbanken aus dynamischen Datensätzen bestehen.Wir können hier nur abstrakt erörtern, das muss ich auch beim programieren so machen.

    Nein - nicht sagen wie du es machen willst. Einfach erklaeren _was_ du machen willst. Und zwar mit der richtigen terminologie.

    Und was Assembler angeht muss ich hier auch noch was loßwerden, Ich programiere mit Assembler jetzt schon seit ca 15 Jahren Opjekt Orientiert und solche Sachen wie X11 oder QT sind nichts besonderes in Assembler und durchaus einfacher zu programieren als mit C++. Sowas wie X11 und QT in Einem habe ich schon in Assembler programmiert - das waren noch Zeiten unter DOS ...

    Und dennoch bist du unfaehig ein Problem zu _beschreiben_?

    2.) Mit Assembler kann ich halt den kompletten dynamischen Datensatz auf einmal einlesen und c++ die nötige Info dazu liefern (Laufzeitimplementierung).

    Du kannst in C++ sehr wohl nur rohe daten anfassen...

    Was braucht ihr da für Info? - Wenn es in diesem Block nicht stehen sollte.

    Eine korrekte terminologie brauche ich und keine erklaerung was du mit basisklassenzeiger machen willst oder sonstwas. ein _was_ du machen willst brauche ich, kein _wie_.

    Erklaer die Aufgabenstellung einfach mal so, wie du sie einem Schueler stellen wuerdest. zB:

    Wir haben ein Datenbank System entwickelt. Nun brauchen wir eine Moeglichkeit Daten unterschiedlicher Typen hinein zuschreiben und wieder auszulesen. Das Problem dabei ist nun, dass der Client Code nicht weiss welchen Typ ein Datensatz hat. Wir brauchen daher ein vereinheitlichtes system um auf 50 verschiedene typen ueber das selbe interface zugreifen zu koennen.

    So in der Art bitte.

    Wie sieht es nun mit void *zeiger aus? Ist der Geltungsbereich dann nur innerhalb der Funktion, in der ich diesen void *zeiger benutze?

    Aeh... Das sind eigentlich Grundlagen - programmierst du wirklich schon 3 jahre lang in C++?
    Naja, jedenfalls: eine variable (ein zeiger ist auch nur eine variable) ist in ihrer gueltigkeit durch ihren Scope beschraenkt. Der Speicher auf den ein Zeiger zeigt unterliegt ebenfalls einem Scope: speicher am Stack wird geloescht wenn die stack-variable out of scope geht. Speicher der am Free Store liegt, bleibt solange bestehen bis er explizit geloescht wird (delete).

    Oder überträgt sich das auf die nächsten Aufrufe? Jeder Aufruf der Funktion ist ja mit einem Zeiger auf einen Typ, der eine Länge hat, die sich von der des vorherigen Aufrufs unterscheidet. Ich vermute mal, daß der Geltungspereich die Funktion ist und somit void *auf_gleiche_laenge nur innerhalb der Funktion gilt.

    Das ergibt fuer mich keinen Sinn.
    sizeof(void*) und sizeof(T*) sind uebrigens gleich gross...



  • ~john schrieb:

    ...sabber...

    Es gibt noch andere Dinge als Unix und Windows. DSPs z.B., oder Mikrocontroller. Oder die gute alten VAX und deren Nachfolger. Irgendwie habe ich da so meine Probleme die der Portabilität, wenn ich Unix-Libraries benutze. Keine Ahnung, woher das kommt. 🙄

    Und Mist baut man nicht, wenn man von einer spezifischen Anordnung der Daten ausgeht (dann ist man sich nämlich der Probelematik bewusst), sondern wenn man sie außer Acht lässt.



  • Ich kann dier ja mal meine Projektseite geben, dannn muss ich hier nicht so viel erklären und du hast vielleicht auch eine bessere Vorstellung der Problematik. Also es geht um die Datenbanken und es sind ca.50 unterschiedliche Typen nötig um diese Datensätze zu verarbeiten (geschätzt), die Datenbankenstructur wurde gerade komplet überarbeitet - also die veröffentlichte Struktur (Download .pdf) ist veralted! Aber das Prinzip ist ziemlich gleich geblieben.

    http://keda.berlios.de/

    Wie du siehst können keine vorgefertigten Datenbanken eingesetzt werden. Ich muss diese Datenbankklasse von Grund auf selbst schreiben!

    Wie kann ich das mit viod* noch genauer erkären ... O.K. 3. Anlauf

    void PartBase::read( void *unterschiedlich_lange_typen , int laenge )
       {
       Einlesen von laenge Bytes, bei Bedarf mehrmals(- warscheinlich eher nicht) auf die Basisadresse *unterschiedlich_lange_typen. 
       }
    

    Jetzt müsste doch klar sein um awas es geht?
    Funktioniert das? Nach meiner Rechersche - Ja.
    Ich will halt nicht Tausende Zeilen schreiben und dann beim Probelauf auf eine Datenbank feststellen, daß das irgendwo nicht funktioniert.

    Shade Of Mine schrieb:

    Wir haben ein Datenbank System entwickelt. Nun brauchen wir eine Moeglichkeit Daten unterschiedlicher Typen hinein zuschreiben und wieder auszulesen. Das Problem dabei ist nun, dass der Client Code nicht weiss welchen Typ ein Datensatz hat. Wir brauchen daher ein vereinheitlichtes system um auf 50 verschiedene typen ueber das selbe interface zugreifen zu koennen.

    Irgendwie ist dann doch die Problematik sehr gut durchgedrungen.
    Ich kann dein Beisbiel voll und ganz so stehen lassen! Daß jedoch niemand auf die Idee kommt einfache Datensätze anzunehmen wo standard Datenbanken Anwendung fänden, müsste man noch auf die dynamischen Datensätze hinweisen.

    asc schrieb:

    1. typedef struct ist redundant. Jede struct, class, enum, union ist bereits eine Typdefinition. Das typedef lässt man daher weg. Nachfolgender Code definiert einen Typ xtyp:

    struct xtyp { int x; };
    

    Dank dir! Jetzt fällt es mir auch auf, daß es Unsinn ist das typedef anzugeben. Und alles passt wieder perfekt zusammen.



  • bastl schrieb:

    Und was Assembler angeht muss ich hier auch noch was loßwerden, Ich programiere mit Assembler jetzt schon seit ca 15 Jahren Opjekt Orientiert und solche Sachen wie X11 oder QT sind nichts besonderes in Assembler und durchaus einfacher zu programieren als mit C++. Sowas wie X11 und QT in Einem habe ich schon in Assembler programmiert - das waren noch Zeiten unter DOS.

    Hmm, naja, ich wollte das zwar eigentlich nicht bewerten, aber die Aussage ist so haarsträubend, dass ich jetzt doch mal mache:
    Also Qt z.B. ist eine Sache bei der alleine die Grundentwicklung schon 7 Jahre gedauert hat. In einem Team mit vielen Leuten in C++. Jede Zeile C++-Code produziert dabei eine ganze Menge Zeilen in Assembler.
    Nun sagst Du, dass Du noch zu DOS-Zeiten so was in Assembler gemacht hast. Du machst das seit 15 Jahren. 1994 hast Du also damit angefangen und konntest das ganze vermutlich noch nicht auf einem ausreichend hohen Niveau um so was wie X11 oder Qt umzusetzen.
    Sagen wir also, Du hast zwei Jahre benötigt, um einen MPP-Assembler (z.B. x86 oder PPC) ausreichend perfekt zu lernen, um hochdynamische, komplexe Programme und Bibliotheken wie X11 und Qt damit zu entwickeln (wobei 2 Jahre schon extrem optimistisch sind).
    Danach hast Du dann also noch zu DOS-Zeiten was Vergleichbares entwickelt. 1998 war DOS schon so ziemlich in den letzten Zuckungen (eher früher), und Du hast in zwei Jahren alleine (klingt zumindest so) was hochgezogen, wozu andere in einer Hochsprache im Team alleine 7 benötigt haben, um eine releasefähige Version zu produzieren?
    Alle Achtung. Du bist der Batman der Informatik... 😉



  • bastl schrieb:

    Ich kann dier ja mal meine Projektseite geben, dannn muss ich hier nicht so viel erklären und du hast vielleicht auch eine bessere Vorstellung der Problematik. Also es geht um die Datenbanken und es sind ca.50 unterschiedliche Typen nötig um diese Datensätze zu verarbeiten (geschätzt), die Datenbankenstructur wurde gerade komplet überarbeitet - also die veröffentlichte Struktur (Download .pdf) ist veralted! Aber das Prinzip ist ziemlich gleich geblieben.

    http://keda.berlios.de/

    Wie du siehst können keine vorgefertigten Datenbanken eingesetzt werden. Ich muss diese Datenbankklasse von Grund auf selbst schreiben!

    Ich habe dich ja schonmal gefragt ob du ein Typsystem brauchst wo ein Query eben unterschiedliche Typen liefern kann und der Client Code den typ vorher nicht kennt.

    Ist eine triviale Sache. Wie das geht habe ich sogar schon erklaert.
    Du hast eine Basisklasse "Typ" oder so aehnlich und davon erben alle anderen Typen. Die meisten Typen-Klassen sind dabei sehr klein und nur sehr wenige haben wirklich komplexitaet drinnen. Uber laufzeit polymorphie kannst du dann den echten Typen bestimmen.

    Oder aber du gehst den Weg den die meisten Datenbanken gehen und bietest mehrere Methoden an um an die Daten zu kommen. Wenn du ein select foo from bar machst, dann machst du nachher zB ein result.get<int>("foo") bzw. result.get<string>("foo"). Dann hast du keine laufzeit polymorphie und sparst dir vermutlich 70% der klassen...

    Wie kann ich das mit viod* noch genauer erkären ... O.K. 3. Anlauf

    Und ich habe dir in jedem von meinen Postings gesagt, dass uns das nichts bringt weil du nicht weisst _wie_ du es loesen willst. also sag mir nicht _wie_ du es machen willst, weil das ist falsch falsch falsch und tut weh.

    void PartBase::read( void *unterschiedlich_lange_typen , int laenge )
       {
       Einlesen von laenge Bytes, bei Bedarf mehrmals(- warscheinlich eher nicht) auf die Basisadresse *unterschiedlich_lange_typen. 
       }
    

    Jetzt müsste doch klar sein um awas es geht?
    Funktioniert das? Nach meiner Rechersche - Ja.

    Habe ich bereits erklaert.
    du kannst entweder mit ::operator new oder mit new char[] laenge Bytes reservieren.

    Mehrmals speicher an der selben adresse reservieren macht dagegen keinen Sinn. Was meinst du damit?
    Du kannst natuerlich speicher an der adresse X reserviern, ihn wieder freigeben und neu speicher reservieren.

    aber new gibt dir halt idR immer eine andere adresse zurueck.

    und in deiner funktion muss der void* natuerlich by reference uebergeben werden...

    Ich will halt nicht Tausende Zeilen schreiben und dann beim Probelauf auf eine Datenbank feststellen, daß das irgendwo nicht funktioniert.

    komplett falscher ansatz.
    und tausende zeilen? wofuer? fuer ein paar typen klassen?
    brauchst du denn 150 mio Typen fuer eine erste test version? reichen da nicht 1-3 typen?

    Irgendwie ist dann doch die Problematik sehr gut durchgedrungen.
    Ich kann dein Beisbiel voll und ganz so stehen lassen! Daß jedoch niemand auf die Idee kommt einfache Datensätze anzunehmen wo standard Datenbanken Anwendung fänden, müsste man noch auf die dynamischen Datensätze hinweisen.

    Und meinst du nicht dass das ein ziemliches Standard Problem ist? Ich meine: wieviele Datenbanksysteme sind in C++ geschrieben? eine Menge. Du bist also bei weitem nicht der erste der vor so einem Typ Problem steht.

    Schau dir doch die APIs an die anderen RDBMS anbieten.



  • Tachyon schrieb:

    7 benötigt haben, um eine releasefähige Version zu produzieren?
    Alle Achtung. Du bist der Batman der Informatik... 😉

    Ich gehemal kurz drauf ein:
    Für dich mag es unwarscheinlich klingen, aber in Assembler hast du andere Möglichkeiten!
    Du formatierst dir deine "Hochsprache" selbst. Du bist verantwortlich für Speichernutzung und Speicherverarbeitung. In C++ benötigst du Deklarationen dazu. Das heißt in Assembler hast du oft nur die Hälfte an Schreibarbeit, dafür musst du mehr wissen! Dann kommt noch hinzu, daß du im OO-Bereich oft nochmals nur 1/3 bis 1/20 der c++ Zeilen in Assembler benötigst.
    So kommst du auf ca. 4 Jahre für eine Lauffähige Umgebung, die nur auf diesem Entwicklungsrechner läuft !!! Den ganzen Kode für kompatibilität sparst du ein! Die Ausführbare Umgebung (.exe) hatte eine Größe von 36 KB das sind dann so um 8 MB Assemblerdateien ( ungefähr, ist schon länger her).
    Ich kann dir mal mein CNC-Projekt sagen, wenn du etwas von NASM verstehst und interessiert bist. Unter Download - Steuerungen - scr-hse-light :
    http://freenet-homepage.de/PCNC/
    Das ist jetzt nicht OO-programmiert aber möglicherweise unterstreicht es meine Fähigkeiten ein bischen.

    Shade Of Mine schrieb:

    Du hast eine Basisklasse "Typ" oder so aehnlich und davon erben alle anderen Typen. Die meisten Typen-Klassen sind dabei sehr klein und nur sehr wenige haben wirklich komplexitaet drinnen. Uber laufzeit polymorphie kannst du dann den echten Typen bestimmen.

    Gilt allse nicht für eine anwendungsoptimierte Datenbank - da muss man selber ran - sorry. Aslo wenn das mit void* funktioniert ist die Sache im Kasten.

    Dann bedanke ich mich bei allen und tschüss.



  • bastl schrieb:

    Du formatierst dir deine "Hochsprache" selbst. Du bist verantwortlich für Speichernutzung und Speicherverarbeitung. In C++ benötigst du Deklarationen dazu. Das heißt in Assembler hast du oft nur die Hälfte an Schreibarbeit, dafür musst du mehr wissen! Dann kommt noch hinzu, daß du im OO-Bereich oft nochmals nur 1/3 bis 1/20 der c++ Zeilen in Assembler benötigst.

    Absoluter Schwachsinn auf der ganzen Linie.

    So kommst du auf ca. 4 Jahre für eine Lauffähige Umgebung, die nur auf diesem Entwicklungsrechner läuft !!! Den ganzen Kode für kompatibilität sparst du ein! Die Ausführbare Umgebung (.exe) hatte eine Größe von 36 KB das sind dann so um 8 MB Assemblerdateien ( ungefähr, ist schon länger her).

    Geht in C++ auch, ohne Probleme.
    Aber du widersprichst dir selber: du sagst du brauchst in assembler weniger zeilen und dann redest du von 8mb source code...

    was natuerlich klar ist: in assembler brauchst du natuerlich deutlich mehr code um das selbe zu erreichen wie in einer hochsprache.

    assembler ist keine magie. C ist im Prinzip nur ein Makro-Assembler. Du hast in Assembler nicht soviel mehr Moeglichkeiten - du bist idR sogar sehr limitiert. Natuerlich kannst du hier und da einen Trick einsetzen den du unter C++ nicht machen kannst (aber dafuer gibt es die moeglichkeit inline asm in C++ zu verwenden).

    Ich kann dir mal mein CNC-Projekt sagen, wenn du etwas von NASM verstehst und interessiert bist. Unter Download - Steuerungen - scr-hse-light :
    http://freenet-homepage.de/PCNC/
    Das ist jetzt nicht OO-programmiert aber möglicherweise unterstreicht es meine Fähigkeiten ein bischen.

    Hab mir das da runter geladen: http://freenet-homepage.de/PCNC/src/pcnc-1.2.7.tar.bz2

    Da sehe ich kein bisschen etwas von ordentlichem Code. Und von Assembler sehe ich auch nix. Wo verstecken sich die Asm Dateien denn?

    Gilt allse nicht für eine anwendungsoptimierte Datenbank - da muss man selber ran - sorry. Aslo wenn das mit void* funktioniert ist die Sache im Kasten.

    Schwachsinn. auf ganzer Linie.

    Aber wenn es dir spass macht, bitte.
    Aber wenn ich mir den PCNC Code ansehe... Du hast noch eine Menge uebers programmieren zu lernen. Nicht falsch verstehen bitte - aber du trittst hier auf als ob du schon jahrelang das alles koenntest, aber dein Code spricht eine komplett andere sprache.

    uU solltest du weniger fixiert auf eine loesung hin arbeiten als vielmehr das problem zu betrachten und eine loesung zu designen.



  • Du formatierst dir deine "Hochsprache" selbst. Du bist verantwortlich für Speichernutzung und Speicherverarbeitung. In C++ benötigst du Deklarationen dazu. Das heißt in Assembler hast du oft nur die Hälfte an Schreibarbeit, dafür musst du mehr wissen!

    diese schlussfolgerung erschließt sich mir nicht. kannst du das mal genauer ausführen?

    kennst du den spruch "wenn man einen hammer hat, sieht alles aus wie ein nagel"? oder konkret auf deine aussagen gemünzt: du kannst assembler, aber kein c++, also ist assemblercode in deinen augen besser, schöner, schneller.
    es ist ja verständlich, dass du dich an dein sauer erlerntes wissen und deine erfahrungen klammerst, aber 1990 ist ja nun schon eine ganze weile her. die hochsprachen und ihre compiler haben sich weiterentwickelt, die hardware auch.

    http://freenet-homepage.de/PCNC/ schrieb:

    Open Source heißt:

    * Sie dürfen nichts für diese Software bezahlen oder verlangen.
    [...]
    * Sie dürfen mit der Anwendung der Software soviel Geld verdienen wie sie wollen.

    die erste aussage ist einfach nur falsch. die zweite widerspricht der ersten.


Anmelden zum Antworten