Stack für beliebige Strukturtypen möglich ?



  • pc() schrieb:

    Ich laß``nen zweiten Stack mitlaufen, der die Typisierungsinformationen trägt. Wenn Dir was Schlaueres eingefallen ist, gib`Bescheid.

    Das mit dem zweiten Stack kapier ich grade nicht.

    Ich meine sowas:

    struct MyStruct
    {
    	// my data...
    };	
    
    // Eine Art Typedeftemplate
    typedef struct MyStruct E;
    
    typedef struct 
    {
    	E* e;
    	int i; // top of stack
    }Stack;
    

    Vor dem Einsatz des Stack muss man MyStruct durch die Struktur, die auf den Stack soll, ersetzt werden.



  • Mittels Macros kann man sich in C pseudo "templates" basteln

    #include <stddef.h>
    
    #define stack_template(Type)                           \
      struct stack_ ## Type {                              \
        size_t n;                                          \
        Type *t;                                           \
      };                                                   \
      struct stack_ ## Type *stack_ ## Type ## _create() { \
        return NULL; /* ... */                             \
      }                                                    \
      // ...
    
    stack_template(int)
    
    int main() {
      struct stack_int *s = stack_int_create();
      // ...
    }
    

    @Stack noob
    Bei deiner Variante machst du ja auch eine harte Typkodierung. Wo ist also der Unterschied ob du nun E schreibst oder E durch struct MyStruct ersetzt?



  • rüdiger schrieb:

    Mittels Macros kann man sich in C pseudo "templates" basteln

    #define stack_template(Type)                           \
      struct stack_ ## Type {
    

    Was machen die Zeilen ?
    Wird nach Ausführung von stack_template(int) aus struct stack_ ## Type
    struct stack_int ?

    rüdiger schrieb:

    @Stack noob
    Bei deiner Variante machst du ja auch eine harte Typkodierung. Wo ist also der Unterschied ob du nun E schreibst oder E durch struct MyStruct ersetzt?

    [/quote]

    Ja, E steht für Strukturelement. MyStruct ist eine Dummy-Struktur. Nach Auslieferung der Stackimplementation kann der Benutzer seine eigene Struktur statt dessen einsetzen. Damit kann der Stack jeden beliebigen Strukturtyp aufnehmen.

    Deine Variante mit den ## Zeichen sieht interessant aus, vielleicht kann man da auch was zur Laufzeit machen.

    😡 Ich muss jetzt leider kopieren gehen 😡



  • Stack nOOb schrieb:

    rüdiger schrieb:

    Mittels Macros kann man sich in C pseudo "templates" basteln

    #define stack_template(Type)                           \
      struct stack_ ## Type {
    

    Was machen die Zeilen ?
    Wird nach Ausführung von stack_template(int) aus struct stack_ ## Type
    struct stack_int ?

    genau. stack_template ist ein Makro, d.h. der Compiler wird zuerst deinen Code durch den Präprozessor schicken. Der Präprozessor ersetzt alle Vorkommen von Makros durch den vom Makro definierten Text (es ist nur eine lexikalische Ersetzung). ## benutzt, um Sachen anzuhängen. Für mehr Info vom siehe http://gcc.gnu.org/onlinedocs/cpp/

    Hier ein Beispiel, was mein GCC 4.1.2 macht:

    ~ $ cat template.c 
    /* um stddef.h nicht zu includieren fuer eine
     * kleine Ausgabe */
    typedef unsigned int size_t;
    #define NULL ((void*) 0)
    
    #define stack_template(Type)                           \
      struct stack_ ## Type {                              \
        size_t n;                                          \
        Type *t;                                           \
      };                                                   \
      struct stack_ ## Type *stack_ ## Type ## _create() { \
        return NULL; /* ... */                             \
      }                                                    \
      // ...
    
    char xxx[] = "Hier wird dein Makro aufgeloest";
    stack_template(int)
    char yyy[] = "Nur eine lexikalische Ersetzung";
    
    int main() {
      struct stack_int *s = stack_int_create();
      // ...
    }
    
     ~ $ gcc template.c -E
    # 1 "template.c"
    # 1 "<built-in>"
    # 1 "<command line>"
    # 1 "template.c"
    
    typedef unsigned int size_t;
    # 16 "template.c"
    char xxx[] = "Hier wird dein Makro aufgeloest";
    struct stack_int { size_t n; int *t; }; struct stack_int *stack_int_create() { return ((void*) 0); }
    char yyy[] = "Nur eine lexikalische Ersetzung";
    
    int main() {
      struct stack_int *s = stack_int_create();
    
    }
    

    erst die Ausgabe von gcc -E wird richtig kompiliert. Wie du siehst, es wurde eine stack_int_create() Funktion erzeugt.



  • supertux schrieb:

    ~ $ gcc template.c -E
    # 1 "template.c"
    # 1 "<built-in>"
    # 1 "<command line>"
    # 1 "template.c"

    Erzeugen die obigen Zeilen eine neue C-Datei, so das man sich

    supertux schrieb:

    typedef unsigned int size_t;
    # 16 "template.c"
    char xxx[] = "Hier wird dein Makro aufgeloest";
    struct stack_int { size_t n; int *t; }; struct stack_int *stack_int_create() { return ((void*) 0); }
    char yyy[] = "Nur eine lexikalische Ersetzung";

    int main() {
    struct stack_int *s = stack_int_create();

    }

    die Datei dann angucken kann ?
    Geht das auch mit Visual Studio ?



  • Stack nOOb schrieb:

    Geht das auch mit Visual Studio ?

    wenn du es nicht selber ausprobierst, wirst du es nie wissen 😉

    btw. ich verstehe deine Frage nicht.



  • Stack nOOb schrieb:

    Was machen die Zeilen ?
    Wird nach Ausführung von stack_template(int) aus struct stack_ ## Type
    struct stack_int ?

    Aaaaah, jetzt hab ichs geschnallt ! 🙂
    Es werden alle Zeilen ersetzt, wo das ## Type steht und die am #define durch das \ Zeichen verbunden dranhängen.
    🕶



  • supertux schrieb:

    Stack nOOb schrieb:

    Geht das auch mit Visual Studio ?

    wenn du es nicht selber ausprobierst, wirst du es nie wissen 😉
    btw. ich verstehe deine Frage nicht.

    Hm..ich kann mich aber auch immer so schön unverständlich ausdrücken. 😃
    Ok, ich versuche es nochmal anders:
    Gibt es einen Compilerschalter "-xyz", sodass eine neue *.c Datei entsteht, in der die Ersetzungen durch den Präprozessor vollzogen sind ?
    // main.c
    //..
    // struct ## Type
    //..

    wird zu
    // main2.c
    //..
    struct stack_int
    //..

    Ok, ist vielleicht Quatsch, braucht man nicht unbedingt.

    Das es funktioniert, hab ich heute morgen schon probiert, kompiliert. ^^
    👍



  • Bei dem GNU GCC genügt es ein -E Flag (siehe mein Beispiel auf Seite 1). Ob der Microsoft Compilier auch sowas hat, weiß ich nicht.



  • Stack nOOb schrieb:

    Hm..ich kann mich aber auch immer so schön unverständlich ausdrücken. 😃
    Ok, ich versuche es nochmal anders:
    Gibt es einen Compilerschalter "-xyz", sodass eine neue *.c Datei entsteht, in der die Ersetzungen durch den Präprozessor vollzogen sind ?
    // main.c
    //..
    // struct ## Type
    //..

    wird zu
    // main2.c
    //..
    struct stack_int
    //..

    Keine Ahnung. Schreib das doch gleich richtig hin, ohne das Kryptozeug.


Anmelden zum Antworten