unions initialisieren



  • Um folgenden Code handelt es sich:

    /* Headerdatei */
    typedef union
    {
      char FAR*   name;
      type_t      type;
      union
      {
        int*      index;
        int FAR** ptr;
        int       value
      } u;
    } GlobalVar;
    extern GlobalVar FAR vartable[];
    
    /* Sourcedatei */
    GlobalVar FAR vartable[] = 
    {
      "Name1", irgendeintyp, {int_pointer},
      "Name2", irgendeinanderertyp, {(int*) (pointer_to_far_int_pointer)},
      "Name3", nocheinanderertyp, {(int*) (int_value)},
      ...
    };
    

    Das Casten in der Initialisierung der union ist allerdings sowohl unschön als auch nicht portabel, aber ohne die Konvertierungen meint der Compiler, die Typen passten nicht zueinander. Gibt es denn eine Möglichkeit, ein anderes Feld einer union als das erste zu initialisieren?

    Moritz



  • audacia schrieb:

    als auch nicht portabel

    warum nicht portabel?



  • volkard schrieb:

    audacia schrieb:

    als auch nicht portabel

    warum nicht portabel?

    Das könnte Probleme geben, wenn int und int* unterschiedlich groß sind (auch wenn ich keine Plattform kenne, bei der das der Fall wäre).
    Wie aber das FAR andeutet, ist der Code für eine 16-Bit-Umgebung mit der dort üblichen Speichersegmentierung. Wenn ich jetzt z.B. noch einen int FAR*-Zeiger als viertes Element in die Union aufnähme und diesen nicht direkt, sondern nur über {(int*) (far_int_pointer)} initialisieren könnte, würden zwei Bytes des vier Byte großen Wertes nicht initialisiert, da ich den Wert ja in einen nur zwei Byte großen caste (oder der Compiler würde sich direkt weigern, den Code zu übersetzen).



  • Mir gefaellt die gesamte Richtung nicht. Entweder habe einen Datentyp oder auch nicht - dabei ist es zunaechst vollkommen egal ob er pointer oder sonst etwas ist. Was Du versuchst, laeuft den Prinzipien der struktrieten Programmierung mit strikten Datentypen zuwieder. Ein "casting" via union gilt aus sehr guten Grund als absolutes NO-NO!



  • MBCS-CITP schrieb:

    Mir gefaellt die gesamte Richtung nicht. Entweder habe einen Datentyp oder auch nicht - dabei ist es zunaechst vollkommen egal ob er pointer oder sonst etwas ist. Was Du versuchst, laeuft den Prinzipien der struktrieten Programmierung mit strikten Datentypen zuwieder. Ein "casting" via union gilt aus sehr guten Grund als absolutes NO-NO!

    Du mißverstehst da etwas, ich will nicht mittels union casten. Es geht um eine Tabelle, die Informationen zur Initialisierung eines Programmteils enthält, darunter auch den Typ (type in der Struktur), der u.a. angibt, welches Feld der union benutzt wird. Die unions verwende ich - dem ursprünglichen Sinne gemäß - um Speicherplatz (den ich auf dem Zielsystem nicht allzu üppig habe) zu sparen. Deswegen suche ich ja einen Weg, ein bestimmtes Feld einer union zu initialisieren, damit ich nicht - wie im Code - in den Typ des ersten Felder der union casten muß.

    Sollte das Problem nicht klar sein, etwas einfacher:

    union MyUnion
    {
      int i;
      float f;
    };
    union MyUnion u = {/* wie initialisiere ich hier das Float-Element? */};
    

    Moritz



  • audacia|off schrieb:

    union MyUnion
    {
      int i;
      float f;
    };
    union MyUnion u = {/* wie initialisiere ich hier das Float-Element? */};
    

    Moritz

    Ich wuerde eine InitMyUnion_f bzw. InitMyUnion_i schreiben:

    void InitMyUnion_f (MyUnion  *pToInit)
    {
        pToInit->f = 1234.5678
    }
    

    (in der Praxis wurde hier noch gegen einen NULL-Ointer abfragen als Argument.



  • MBCS-CITP schrieb:

    audacia|off schrieb:

    union MyUnion
    {
      int i;
      float f;
    };
    union MyUnion u = {/* wie initialisiere ich hier das Float-Element? */};
    

    Moritz

    Ich wuerde eine InitMyUnion_f bzw. InitMyUnion_i schreiben:

    void InitMyUnion_f (MyUnion  *pToInit)
    {
        pToInit->f = 1234.5678
    }
    

    (in der Praxis wurde hier noch gegen einen NULL-Ointer abfragen als Argument.

    Die Tabelle liegt zur Laufzeit in nicht mehr veränderbarem Speicher, und da möchte ich sie eigentlich auch haben...



  • Sie entsteht doch als Object erst zur Laufzeit. Erst mit

    MyUnion unMyData;
    

    bzw.

    MyUnion *pMyData;
    
    pMyData = malloc (sizeof (MyUnion))
    

    entstehen doch die Unions im Stack bzw. im Heap.



  • audacia schrieb:

    typedef union
    {
      char FAR*   name;
      type_t      type;
      union
      {
        int*      index;
        int FAR** ptr;
        int       value
      } u;
    } GlobalVar;
    

    Ich denke du meinst "typedef struct" anstatt "typedef union" oder ?

    Wegen dem direkten Ansprechen:

    In C99 *könnte* sowas klappen:

    GlobalVar FAR vartable[] =
    {
    "Name1", irgendeintyp, i.index = int_pointer},
    "Name2", irgendeinanderertyp, i.ptr = pointer_to_far_int_pointer},
    "Name3", nocheinanderertyp, i.value = int_value},
    ...
    };

    wobei ich das nicht ausprobiert habe.



  • MBCS-CITP schrieb:

    Sie entsteht doch als Object erst zur Laufzeit.

    Nein, als initialisierte Struktur steht die Tabelle sozusagen im Code-Segment der ausführbaren Datei, und dort kann man nicht reinschreiben. Würde ich die Tabelle komplett zur Laufzeit initialisieren, hätte sie ja gar keinen Sinn mehr.

    feigling schrieb:

    Ich denke du meinst "typedef struct" anstatt "typedef union" oder ?

    Ja, stimmt.

    feigling schrieb:

    Wegen dem direkten Ansprechen:

    In C99 *könnte* sowas klappen:

    GlobalVar FAR vartable[] =
    {
    "Name1", irgendeintyp, i.index = int_pointer},
    "Name2", irgendeinanderertyp, i.ptr = pointer_to_far_int_pointer},
    "Name3", nocheinanderertyp, i.value = int_value},
    ...
    };

    Danke für den Vorschlag, aber das klappt leider nicht; der Compiler unterstützt ohnehin kein C99.

    Moritz


Anmelden zum Antworten