dieselbe definierte struct in mehreren Dateien nutzen



  • Guten Morgen,

    wie kann ich eine struct in einer Header Datei Deklarieren dann einmal definieren und dann in allen weiten Modulen nutzen, nur wenn ich den Header inkludiere? Bei Variabeln geht dies mit extern, aber wie funktioniert dies bei Structs? Ich bräuchte also sowas wie eine globale Structur die einmal definiert wird und die ich dann in allen Sourcedateien nutzen kann, also auch auf die inneren Elemente zugreifen kann(mystruct.element = 42).



  • Das geht genauso.

    Im Header:

    struct soso
    [
     ...
    };
    
    extern struct soso mystruct;
    

    und in einer C-Datei dann:

    struct soso mystruct;
    


  • Danke, mein Problem hat sich erledigt. Ich hatte einfach einen Schreibfehler bei den Bezeichner drinne 🙂 Es geht jetzt ohne extern, indem ich gleich in der Headerdatei deklariere und auch definiere.



  • SchulterNichtMehrZuck schrieb:

    Es geht jetzt ohne extern, indem ich gleich in der Headerdatei deklariere und auch definiere.

    Dann wird in jeder Übersetzungseinheit (.c Datei), die deinen Header einbindet eine neue globale Variable angelegt.
    Und dann hängt es vom Linker ab, was er damit macht.

    Globale Variablen werden in einer .c-Datei definiert, damit es auch nur eine Variable gibt.



  • Geht das auch so gut?

    Header

    // Deklaration
    extern struct MyStruct{
        int i;
        float f;
    }s; // <--- Wird hier nicht schon mit 0 definiert?
    

    Source

    // Einmalige Definition
    struct MyStruct s = {42, 3.141f};
    


  • Nein, das geht so natürlich nicht.
    extern ist zwar als Speicherklassenspezifizierer tituliert, macht aber eben gerade gar nichts mit Speicher und dient ausschließlich zur Namensbekanntmachung (eines irgendwo anders) definierten Objektes (für den Compiler). D.h. der Compiler erledigt seine Arbeit, weil er davon ausgeht, dass mittels extern gekennzeichnete Objekte schon irgendwo definiert sind. Und wenn das dann doch nicht der Fall sein sollte, (da der Compiler jede Quelldatei einzeln abarbeitet und keine übergreifenden Abhängigkeiten erkennt) kommt es zu den bekannten Fehlern wie "undefined reference..." o.ä., die aber dann vom Linker kommen, weil der die einzelnen von Compiler erzeugten Objektdateien zusammenbasteln muss, das aber nicht kann, da er die angegebene Variable/Funktion nirgends finden kann.
    Mittels extern kannst du keine (irgendwo anders definierten) struct-Typen bekannt machen, das geht nur für Objekte bzw. mit Abstrichen bei Funktionen.
    Üblich ist also

    bla.h
    struct meinTyp { int i; char c; };
    oder
    typedef struct { int i; char c; } meinTyp;
    
    bla.c
    #include "bla.h"
    
    struct meinTyp x; /* hier erst wird die Variable vom Typ "struct meinTyp" definiert */
    bzw.
    meinTyp x; /* hier erst wird die Variable vom Typ "meinTyp" definiert */
    

    In der .c Datei ist durch das Einschließen der Headerdatei der Typ schon bekannt, und kann verwenden werden, extern für eine reine Typdefinition ist sowieso Unsinn.



  • Ich kann also kein globales Objekt einer Struktur nutzen? In meinen Fall geht es um eine Fehlerstruktur die eine Nummer und einen Text vom letzten aufgetreteten Fehler enthält, damit sie an anderer Stellen bei Bedarf ausgelesen und geloggt werden kann. Diese Stuktur soll einmal deklariert werden und dann von allen Modulen genutzt werden können, so dass dasselbe Objekt aber in den Modulen verfügbar ist und nicht jedes Modul sein eigenen Objekt davon erzeugt.

    Wie mache ich dies am besten?



  • SchulterZuck schrieb:

    Ich kann also kein globales Objekt einer Struktur nutzen?

    Das hat doch keiner gesagt. Bitsy hat es doch oben schon vorgemacht:
    Im Header die Struktur definieren und eine Variable vom Typ der Struktur mit Schlüsselwort extern deklarieren.

    Dann in einer C-Datei die Variable definieren, also noch mal:
    Header:

    ...
    typedef struct
    {
       int i;
    } bla;
    
    extern bla variable;
    ...
    

    Dann in irgendeiner C-Datei:

    ...
    bla variable;
    ...
    


  • Doch, kannst du, wie schon beschrieben, du definierst in einer .c-Datei die Struktur, und in allen anderen .c-Dateien, die diese Struktur verwenden sollen, muss der Compiler eine extern-Deklaration (oft in einer eigenen .h-Datei mit evtl. noch weiteren extern-Deklaration enthalten, die dann in die entsprechenden .c-Dateien eingebunden werden) vorfinden.

    MfG,

    Probe-Nutzer



  • Also das hier geht:

    /* HEADER */
    typedef struct
    {
       int i;
    } bla;
    
    extern bla variable;
    

    und das nicht?

    /* HEADER */
    extern struct bla
    {
       int i;
    }variable;
    


  • Probiers aus.



  • Ich habe das zweite ja ausprobiert und es funktioniert, aber hier wurde ja gesagt dass dies nicht geht bzw. vom compiler/linker abhängt wie er das interpretiert.

    Da ich es also selbst nicht testen kann, frage ich die Fachmänner hier.



  • Genial. MSVC frißt's wirklich.
    Es gibt auch kein Problem weitere Variablen des Typs bla zu definieren.
    Es ist immer wieder verblüffend wie tolerant C/C++ sind.
    Aber - das ist dann auch eine Stilfrage - und das grenzt an 'makaber'.


Anmelden zum Antworten