Passendes Array zum Namen ( Macros? )



  • Hi

    Ich habe eine Menge von const int[] - Arrays mit Namen:
    LengthRDPacketHeader
    LengthTickRules
    LengthMatchRules

    Nun benötige ich eine Funktion, die zu einem string ( const char *name )
    das passende Array zurückliefert.

    Die sieht derzeit so aus:

    inline const int *GetLengthArray( const char *name, int &len )
    {
        const int *ar = 0;
        len = 0;
        if ( strcmp( name, "RDPacketHeader" ) == 0 )
        {
            ar = LengthRDPacketHeader;
            len = sizeof( LengthRDPacketHeader ) / sizeof( int );
        }
        else if ( strcmp( name, "TickRules" ) == 0 )
        {
            ar = LengthTickRulesSequence;
            len = sizeof( LengthTickRulesSequence ) / sizeof( int );
        }
        else if ( strcmp( name, "MatchRules" ) == 0 )
        {
            ar = LengthMatchRulesSequence;
            len = sizeof( LengthMatchRulesSequence ) / sizeof( int );
        }
        ...
    }
    

    Das ist natürlich viel Tipparbeit,da noch viel mehr dieser Arrays vorliegen.
    Nun möchte ich das gern vereinfachen.

    Ich bin leider kein Experte für Macros, aber ich vermute, dass es mit Macros nicht geht, weil die ja zur Compilezeit verarbeitet werden, ich den Namen des gewünschten Arrays aber erst zur Laufzeit kenne.

    Jemand ne bessere Idee?



  • Nö...



  • sizeof wird genauso wie Makros zur Compilezeit aufgelöst (außer bei VLA), dein Vorschlag ist also unbrauchbar, wie du schon richtig erkannt hast.

    Du kannst die Arraynamen als Stringliterale sortiert hinterlegen und alle deine einzelnen int-Array in ein Gesamt int[][] zusammenfassen;
    du erreichst also mit entsprechendem Datendesign schon mal weniger komplexen Code:

    enum {ANZAHL=3,LAENGE=10};
    
    int get(const char *name)
    {
      char (*x)[40],a[][40]={"LengthMatchRules","LengthRDPacketHeader","LengthTickRules"};
      return x=bsearch(name,a,ANZAHL,40,strcmp),x-a;
    }
    
    int main()
    {
      int Alle[ANZAHL][LAENGE]={{0,1,2,3}, /* LengthMatchRules */
                                {4,5},     /* LengthRDPacketHeader */
                                {6,7,8,9}  /* LengthTickRules */
                                };
    
      int x,*i;
      for(x=0,i=Alle[get("LengthRDPacketHeader")];x<LAENGE;++x) printf("%d\n",i[x]);
      for(x=0,i=Alle[get("LengthTickRules")]     ;x<LAENGE;++x) printf("%d\n",i[x]);
      for(x=0,i=Alle[get("LengthMatchRules")]    ;x<LAENGE;++x) printf("%d\n",i[x]);
    
      { /* falls du die Arrays einzeln verwenden willst, kannst du dich aus dem Gesamt-Array bedienen: */
        enum {LengthMatchRules_,LengthRDPacketHeader_,LengthTickRules_};
        int *LengthMatchRules    =Alle[LengthMatchRules_];
        int *LengthRDPacketHeader=Alle[LengthRDPacketHeader_];
        int *LengthTickRules     =Alle[LengthTickRules_];
      }
    
      return 0;
    }
    

  • Mod

    Du kannst aber immerhin dir viel Tipparbeit sparen, nach dem Muster des Beispiels hier:
    http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html

    Was mich eher wundert ist das Design. Reflection zu brauchen ist in C eher ungewöhnlich. Wozu? Außerdem scheinen die Felder global zu sein. Super böse. Hier liegen die wahren Ansätze, wie du dein Programm verbessern kannst. Wir können dir dabei helfen. Also nimm bitte möglichst nicht die Makrolösung sondern beschreib mal genau, warum du glaubst, so ein Konstrukt überhaupt zu benötigen und warum alles global ist.

    Eine kleine Schwäche ist noch, dass du die Typen hardcodiert hast, was auch nicht toll ist. sizeof(X)/sizeof(int) -> sizeof(X)/sizeof(*X) . Eine ganz einfache Änderung, aber schon ist das ohne jeden Nachteil viel flexibler gegenüber Wartungsarbeiten und Änderungen.

    Wozu ist überhaupt ar da?

    ⚠ Bei const int * als Rückgabewert wird mir auch Angst und Bange. Das ist fast garantiert ein grober Fehler! ⚠

    inline scheint auch nicht unbedingt angebracht für solch eine Monsterfunktion. Die hat nichts in Headern zu suchen. Das ist auch keine universelle Hilfsfunktion, die man auch mal Header-only implementieren kann, da sie ganz speziell für dein Programm ist.

    Du siehst, hier sind noch sehr viele Baustellen. Alle sind sie wesentlich dringender als deine eigentliche Frage. Kümmere dich um diese Fehler zuerst! Besonders der Ruckgabewert ist fatal. Und die Frage danach, wozu das ganze eigentlich gut sein soll.


Anmelden zum Antworten