partieller Code (include *.c file) schlechter Stil?



  • Guten Morgen,

    eine weitere Frage an Euch;) ich habe einen Pool an verschiede Definition. Nun möchte ich diese Definition in verschiedene Dateien aufteilen zur Übersichtlichkeit bzw. Lesbarkeit.

    Beispiel:

    //pool.h
    typedef struct stDef 
    {
      int someinfo;
    } stDef ;
    
    stDef getDef(const tSIZE id);
    
    //pool.c
    
    #include "foo.c"
    #include "bar.c"
    
    stDef getDef(const tSIZE id)
    {
     static stDef definitions[2]={0};
    definitions [0] = part_Foo();
    definitions [1] = part_Bar();
    
    return stDef [id];
    }
    

    und hier die definitionen:

    //foo.c
    
    static part_Foo()
    {
     stDef def { 42 };
    return def;
    }
    
    //bar.c
    
    static part_Bar()
    {
     stDef def { 123 };
    return def;
    }
    

    aber mir gefällt das nicht so ganz, ist das schlechter still, wie könnte ich das "eleganter" lösen?

    grüße und Danke


  • Mod

    Include von Dateien mit Definitionen drin wird dir normalerweise um die Ohren fliegen, weil du dann mehrfache Definitionen des gleichen Dings bekommst. Ist deshalb bei dir alles static? Weil das den Compiler ruhig gestellt hat?

    Ansonsten musst du zuerst einmal erklären, wieso du das überhaupt gemacht hast. Header sind dir ja offensichtlich bekannt. Wieso benutzt du sie hier nicht?



  • @SeppJ sagte in partieller Code (include *.c file) schlechter Stil?:

    Include von Dateien mit Definitionen drin wird dir normalerweise um die Ohren fliegen, weil du dann mehrfache Definitionen des gleichen Dings bekommst. Ist deshalb bei dir alles static? Weil das den Compiler ruhig gestellt hat?
    Ansonsten musst du zuerst einmal erklären, wieso du das überhaupt gemacht hast. Header sind dir ja offensichtlich bekannt. Wieso benutzt du sie hier nicht?

    ja static erst mal zum "ruhigstellen" der compilers. du meinst ich sollte lieber zu jeder def foo + bar eine header machen.. und dann nur diese includieren.. macht natürlich auch sinn.. 😉 je wo wir drüber reden;)

    dadurch dass nur die die pool.c bar/foo kennt/verwendet .. dachte ich mir ich kann mirfoo.h/bar.h sparen da ich ja direct c includieren kann..

    EDIT: unabhängig davorn, wie könnte ich den so ein pool mit (def) gekappelst sonst designen?


  • Mod

    @SoIntMan sagte in partieller Code (include *.c file) schlechter Stil?:

    ja static erst mal zum "ruhigstellen" der compilers.

    Dass das eine gefährliche Praxis ist, muss ich wohl nicht erklären, oder? Stell dir mal vor, du wärst noch eine Ebene weiter gegangen, hättest pool.c auch ohne Header eingebunden, und daher getDef auch static gemacht. Das wäre ein lustiges Problem.

    du meinst ich sollte lieber zu jeder def foo + bar eine header machen.. und dann nur diese includieren.. macht natürlich auch sinn.. 😉 je wo wir drüber reden;)

    Genau.

    EDIT: unabhängig davorn, wie könnte ich den so ein pool mit (def) gekappelst sonst designen?

    Ist schon okay so, wenn das wirklich zwei Variablen sein sollen, die irgendwie global verfügbar sein sollen. (Warum man gleich mehrere globale Variablen haben sollte, ist natürlich immer zweifelhaft, aber das will ich nicht das Thema machen). Ein allgemeiner Pool sollte natürlich viel weniger statisch sein, aber das ist ja offensichtlich nicht das Ziel, und man muss es ja nicht übertreiben und Dynamik einbauen, die man gar nicht braucht.



  • @SeppJ sagte in partieller Code (include *.c file) schlechter Stil?:

    Ist schon okay so, wenn das wirklich zwei Variablen sein sollen, die irgendwie global verfügbar sein sollen. (Warum man gleich mehrere globale Variablen haben sollte, ist natürlich immer zweifelhaft, aber das will ich nicht das Thema machen). Ein allgemeiner Pool sollte natürlich viel weniger statisch sein, aber das ist ja offensichtlich nicht das Ziel, und man muss es ja nicht übertreiben und Dynamik einbauen, die man gar nicht braucht.

    ja im Endeffekt ,werden die Definitionen später generiert und fixiert, sie fungieren wie templates welche hardcodiert im code hinterlegt sind. konstante Eigenschaften die nie wieder angefasst werden (wie Naturkonstante:) .

    Gibt es einen neues template wird neu versioniert. usw.

    EDIT: deswegen static.. ja ich weiss die const qualifiert fehler noch:)


  • Mod

    @SoIntMan sagte in partieller Code (include *.c file) schlechter Stil?:

    EDIT: deswegen static.. ja ich weiss die const qualifiert fehler noch:)

    Ich würde eher sagen, du hast schon zu viele const in deinem Code.

    So eine Aussage von mir 😲

    Du übergibst sowohl deine Parameter als auch deine Rückgabewerte per Kopien. Wen interessiert, ob du den Parameter dann intern änderst oder nicht? Und Rückgabekopien sind sowieso, ich weiß nicht die C-Terminologie, aber in C++ würde man "R-Value" sagen. Sprich: Du kannst sie sowieso nicht ändern. Du kannst schließlich nicht

    int x(){return 5;}
    
    ...
    
    x() = 6;
    

    machen, egal ob da nun int x() oder const int x() stünde.

    Wenn das natürlich nur vereinfachter Beispielcode ist, und da irgendwelche Pointer eine Rolle spielen, dann ist das const natürlich wichtig. Dann aber um so mehr Vorsicht mit den statics, ob die Objekte, auf die du zeigst, auch wirklich existieren.



  • Dieser Beitrag wurde gelöscht!


  • @SoIntMan sagte in partieller Code (include *.c file) schlechter Stil?:

    dadurch dass nur die die pool.c bar/foo kennt/verwendet .. dachte ich mir ich kann mirfoo.h/bar.h sparen da ich ja direct c includieren kann..

    Wenn static nur zum "ruhigstellen" war und die Sichtbarkeit hier nicht wichtig ist, dann kannst du dir in dem Fall die Header auch sparen, indem du deren Inhalt (die Deklarationen von part_Foo und part_Bar) direkt in die pool.c schreibst:

    // pool.h
    typedef struct stDef 
    {
      int someinfo;
    } stDef ;
    
    stDef getDef(const int id);
    
    //pool.c
    #include <pool.h>
    
    stDef part_Foo();
    stDef part_Bar();
    
    stDef getDef(const int id)
    {
        static stDef definitions[2] = {0};
        definitions[0] = part_Foo();
        definitions[1] = part_Bar();
        return definitions[id];
    }
    
    // def.c oder alternativ eine foo.c und eine bar.c.
    #include <pool.h>
    
    stDef part_Foo()
    {
        stDef def = { 42 };
        return def;
    }
    
    stDef part_Bar()
    {
        stDef def = { 123 };
        return def;
    }
    

    Das ist Äquivalent zur Lösung mit den 2 Headern, nur eben ohne die 2 extra Dateien. Das würde ich für so etwas simples auch in der Form bevorzugen. Zu viele Dateien können ein Projekt auch unübersichtlich machen.

    Oder alternativ auch ohne Funktionen und direkt mit globalen Variablen:

    //pool.c
    #include <pool.h>
    
    extern stDef myproject_foo_def;
    extern stDef myproject_bar_def;
    
    stDef getDef(const int id)
    {
        static stDef definitions[2] = {0};
        definitions[0] = myproject_foo_def;
        definitions[1] = myproject_bar_def;
        return definitions[id];
    }
    
    // def.c oder alternativ eine foo.c und eine bar.c.
    #include <pool.h>
    
    const stDef myproject_foo_def = { 42 };
    const stDef myproject_bar_def = { 123 };
    

    Die sind dann in der Form zumindest nicht für jeden sichtbar, der pool.h einbindet.
    Probleme mit Initialisierungsreihenfolge natürlich erstmal außen vor. Mit den Variablen sollte man getDef natürlich erst aufrufen, wenn die globalen Konstruktoren durch sind (im Zweifel frühestens ab der main()). Ansonsten machen die Funktionen mehr Sinn.


  • Mod

    @Quiche-Lorraine : Ich weiß nicht, wieso du es gelöscht hast, aber ich erinnere mich noch was da stand (und ich kann meine Moderatorenfähigkeiten einsetzen, um die Geschichte zu sehen 😉 ), aber ich kann dir als Feedback geben, dass das eigentlich ein solider Vorschlag war.


Anmelden zum Antworten