was ist an klassendefinition falsch?



  • Natürlich kannst Du auch auf solchen Systemen mit Polymorphie arbeiten, wobei ich mir kaum vorstellen kann, dass es nicht zumindest new für Objekte gibt (auch wenn die nicht auf dem Heap abgelegt werden sollten). Ansonsten kann man immernoch Standardcontainer einsetzen, um Objekte zu halten.



  • LordJaxom schrieb:

    Ansonsten kann man immernoch Standardcontainer einsetzen, um Objekte zu halten.

    Was meinst du, wie die intern arbeiten? 😛

    ohne new ist es zwar nicht vollkommen unmöglich, aber es erschwert die ganze sache natürlich ungemein - mir wären es zu viele einschränkungen, um das zu tun^^

    bb



  • Hallo zusammen,

    erst einmal danke für eure zahlreichen Kommentare. Mein Zielsystem ist ein 8 MHz MSP430 mit 10 kB RAM und 48 kB Flash. Darauf läuft eine Art Runtime, welche ein C ohne malloc und Co bietet. Mein Algorithmus soll ich aber für einen C++ basierten Simulator schreiben, wobei aber keine Elemente zur Anwendung kommen, welche auf dem Zielsystem nicht verfügbar sind. Daher der Zwangsweise verzicht auf new, malloc und Co., die einzige pseudo Dynamic, welche mir zur Verfügung steht, ist ein BufferPool, welcher eine beschränkte Anzahl von Elementen eines bestimmten Listentypes bereitstellt.

    Ist es ne gute Idee, die Expression erst zu zählen, dann lokal ein Pointerarray zu erstellen und dies dann zu verwenden für Stack based Polymorphismus?

    uwe



  • wenn du eh einen pool hast, aus dem du "fake"-dynamischen speicher bekommen kannst, dann verwende placement new oder schreib einen eigenen operator new à la

    static char dynamic_memory[1024];
    size_t counter;
    
    void* operator new (size_t s)
    {
       if (counter + s > 1024) 
         throw bad_alloc();
       else
       {
          counter += s;
          return dynamic_memory + counter - s;
       }
    }
    

    im prinzip.



  • Zielsystem ist ein 8 MHz MSP430 mit 10 kB RAM und 48 kB Flash. Darauf läuft eine Art Runtime, welche ein C ohne malloc und Co

    That's hard. Selbst arbeite ich grade an einem Scheme Interpreter fuer den embedded Bereich. C++ und Polymorphie kann ich dort aber auch nicht nutzen (so gern ich es taete). Die Allgemeine Struktur eines jeden Elements sieht etwa so aus (frei aus tinyscheme kopiert):

    /* cell structure */
    struct cell {
      unsigned int _flag;
      union {
        struct {
          char   *_svalue;
          int   _length;
        } _string;
        num _number;
        port *_port;
        foreign_func _ff;
        struct {
          struct cell *_car;
          struct cell *_cdr;
        } _cons;
      } _object;
    };
    

    Das _flag gibt den Typ an (String, Number, Symbol, Pair, ...). Daraus sind dann alle anderen Elemente wie Listen oder Baeume aufgebaut. Es ist mit automatischem memory management und man erhaelt mittels get_cell aus dem Pool von Zellen eine neue. Es ist das Aequivalent zu new. Auch muss die Runtime etwas aequivalentes wie malloc und Co. anbieten. Ansonsten muss man sich seinen eigenen memory manager fuer die 10kByte Ram schreiben.



  • Hallo zusammen,

    also die Geschichte mit dem eigenen new finde ich wirklich witzig. Da muß ich doch in der Tat mal schauen, ob ich das nicht verwenden kann. Mein Betreuer will, dass ich alles statisch definiere, was damit ja im Prinzip auch erfüllt wäre, aber dennoch einiges an Lebenserleichterung bringen würde.

    @knivil
    So ein "Monster" habe ich bis jetzt im alten C basierten Simulator verwendet. Ich hatte allerdings gehofft, die Welt ein bisschen schöner zu machen. Was ich bei deinen Ansatz aber nicht versteh sind zwei Dinge:

    1. Wo legt du die Verweise auf die Blätter ab? In car und cdr?

    2. Wie und wo erzeugst du die Cellen statisch und legst diese ab? Über den Pool?

    uwe



  • uwerothfeld schrieb:

    1. Wo legt du die Verweise auf die Blätter ab? In car und cdr?
    2. Wie und wo erzeugst du die Cellen statisch und legst diese ab? Über den Pool?

    zu 1) Jein. Scheme ist etwas anders. Z.B. ist (+ 1 2) ein Befehl zur Addition und wird in einer einfachen Liste gespeichert. car hat einen Zeiger auf eine Zelle vom Typ Symbol (+) und cdr enthaelt einen Pointer auf den Rest der Liste. (Ich empfehle dir aber eine Einfuehrung in Lisp/Scheme zu lesen, hier kann ich so schlecht Bildchen malen.) Ein Versuch:

    [car|cdr]---[car|cdr]---[car|/]
      |           |           |
      Symbol      Number      Number
       name: +     value: 1    value: 2
    

    Waehrend [/] ein Verweis auf das Nullelement ist und den Abschluss einer Liste kennzeichnet. Mit diesen rudimentaeren Konstrukten koennen alle moeglichen Expressions gebaut werden.

    zu 2) Neue Elemente werden mit z.B. cons oder mk_number konstruiert, sie Rufen get_cell auf und fordern vom Pool (beim Start initialisiert) eine freie Zelle an. Dazu Verweise ich aber erstmal auf den (haesslichen) Sourcecode von Minischeme.



  • Hallo zusammen,

    ich glaube ich habe verstanden 🙂

    uwe



  • Hallo nochmal,

    ich habe nun meine Klasse ergänzt um:

    //define a list to store all expressions
        static ASTExpression expressionList[DSM_EXPRESSION_CNT_MAX];
    
        //this index points to the next free element in the storage
        static size_t expressionlistIndex = 0;
    

    sowie

    /**
     * Overload the new operator to simulate dynamic memory allocation.
     */
    static void* ASTExpression::operator new (size_t size){
    
        if(expressionlistIndex + size > DSM_EXPRESSION_CNT_MAX){
            throw bad_alloc();
        }//End if
        else {
            expressionListIndex += size;
            return expressionList + expressionListIndex - size;
    
       }//End else
    }//End operator new
    

    Allerdings bekomme ich als Fehler:

    In file included from source/tinyDSMMain.cpp:12:
    source/ast/astexpression.h:118: Fehler: ISO-C++ verbietet Initialisierung des nicht konstanten statischen Elements »expressionlistIndex« in der Klasse
    

    Aber den Index auf den Speicher muß ich doch global initialisieren, da er ja für alle Objekte gilt. Wo ist mein Denkfehler????

    Danke nochmal.
    Uwe



  • Die Initialisierung der statischen Elemente muss außerhalb der Klasse (in der cpp) erfolgen. Genau das sagt der Compiler ja auch.



  • static size_t expressionlistIndex
    

    Probier' es mit

    size_t ASTExpression::expressionlistIndex = 0;
    

    in der Cpp-Datei.



  • Hi,

    ah, so gehts! Fein. Jetzt habe ich nur noch nen letztes Problem. Ich bekomme in der Zeile:

    return expressionList + expressionListIndex - size;
    

    folgenden Fehler:

    /source/ast/astexpression.cpp:179: undefined reference to `AST::ASTExpression::expressionList'

    Was mach ich den falsch (expressionlist habe ich nochmal umbenannt nach expressionList)? Noch nen Tipp??
    Uwe



  • ASTExpression::expressionList ist ja ebenfalls static. Du hast es bisher nur deklariert (in der Klassendeklaration). Du brauchst auch hier noch eine Definition in der cpp.



  • Hi zum letzten ;),

    nun habe ich in der .h:

    //define a list to store all expressions
        static ASTExpression expressionList[DSM_EXPRESSION_CNT_MAX];
    
        //this index points to the next free element in the storage
        static size_t expressionListIndex;
    

    und in der .cpp:

    //init the static counter for the simulated dynamic storage allocation
    size_t ASTExpression::expressionListIndex = 0;
    ASTExpression ASTExpression::expressionList[DSM_EXPRESSION_CNT_MAX];
    

    Ist das nicht doppeltgemommelt bzgl. der expressionList???

    Uwe



  • Nein, wieso denn?
    Das Erste ist doch nur eine Deklaration in der Klasse. Da die Variable static ist, gehört sie ja nicht zur Klasse und es wird somit auch kein Speicher dafür mit vereinbart. Das machst du durch die Definition in der cpp selbst.
    siehe auch
    http://tutorial.schornboeck.net/staticmember.htm



  • Hallo,

    ok ok. Habe ich glaube ich verstanden. Dann sage ich mal *close*. Hehe. Vielen Dank für Eure Hilfe.

    Uwe


Anmelden zum Antworten