Unterschiedliche Strukturnamen mit gleichem Inhalt (optimale Funktionsübergabe?)



  • Wutz schrieb:

    1. weil du die Eigenschaft von union bzgl. des Member- und Gesamtzugriffs nicht verstanden hast

    Aha.
    Super.
    Das hilft. 👍

    Nicht.



  • vielen Dank für eure Unterstützung.

    Sowohl die Lösung von Wutz, als auch von sebi707 funktioniert. Aber bitte keinen Streit anfangen. Ihr habt wahrscheinlich beide sehr gute Kenntnisse und jeder hat so seinen Stil und seine Vorzüge. Ich bin als Anfänger da noch sehr unvoreingenommen und ich frage nicht, weil ich zu faul bin selbst nach einer Lösung zu suchen. Das ich hier und da etwas noch nicht so schnell verstehe, ist nun mal leider so. Ich habe zuvor mit AutoIt, PureBasic und etwas C programmiert und daher ist es auch eine Phase der Umgewöhnung. ...gerade in Richtung OOP ist da vieles anders.

    Ich bin auf jeden Fall für jede Hilfe und Tipps dankbar, die ich hier bekomme und ich weiß es zu schätzen. Schließlich ist es ja auch eure Zeit und es steht euch frei zu Helfen.

    nochmals Danke an euch allen 😃

    Ich sehe somit die anfangs gestellte Frage als beantwortet 😉

    viele Grüße,
    SBond



  • In jedem Fall musst du sicherstellen, dass das Padding der structs im Fremdmodul das Gleiche wie in deinem eigenen ist.



  • Hallo Wutz,

    dein Code funktioniert aber nur bei exakt gleichem Layout der Substrukturen.
    Hier ein Gegenbeispiel:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct MainStruct {
    
        struct SubStruct1 {
        	int x;
        	int y;
            int Value;
        } s1;
    
        struct SubStruct2 {
        	int y;
            int Value;
            int x;
        } s2;
    
        struct SubStruct3 {
            int Value;
            int x;
            int y;
        } s3;
    
    } MainStruct_t;
    
    typedef union {
        struct SubStruct1 *s1;
        struct SubStruct2 *s2;
        struct SubStruct3 *s3;
        int Value;
    } T;
    
    void setValue( T **t, int i )
    {
      (*t)->Value=i;
    }
    
    int main()
    {
        MainStruct_t x;
        T t;
    
        setValue( (t.s1=&x.s1,&t), 1);
        setValue( (t.s2=&x.s2,&t), 2);
        setValue( (t.s3=&x.s3,&t), 3);
    
        printf( "%d %d %d",x.s1.Value,x.s2.Value,x.s3.Value);
    
        return 0;
    }
    

    http://ideone.com/I9Wqg3

    Beispielausgabe:

    47 134513954 3
    

    Der Makro-Code oder die C++-Lösung mittels Template würde aber auch dann korrekt funktionieren (der Code vom OT bezieht sich ja nur auf den Zugriff auf die Membervariable 'Value').



  • SBond schrieb:

    Sowohl die Lösung von Wutz, als auch von sebi707 funktioniert. Aber bitte keinen Streit anfangen. Ihr habt wahrscheinlich beide sehr gute Kenntnisse und jeder hat so seinen Stil und seine Vorzüge.

    Es sind hier nicht bloß verschiedene Stile. Der Code von Wutz ist der komplizierteste hier vorgeschlagene und funktioniert nur in den seltensten Fällen. Zumindest glaube ich das solange Wutz mir seinen Code nicht erklärt oder ein compilierbares Beispiel liefert, welches richtig funktioniert für structs wo Value an unterschiedlichen Stellen steht (siehe vorheriger Beitrag von Th69). Mich ärgert, dass Wutz einen solch verwirrenden Code einem Anfänger, der noch nicht zwischen einem unnötig komplizierten Code und einer cleveren Lösung für ein tatsächlich kompliziertes Problem unterscheiden kann, präsentiert.

    hustbaer schrieb:

    Wieso zum Geier compiliert das? &t müsste ein T* sein, wie kann man das dann an eine Funktion übergeben die nen T** Parameter hat?

    Der compiliert aufgrund der laxen Konvertierungsregeln in C. In C kann ich einer Funktion, die ein Pointer auf ein int akzeptiert, auch ein Pointer auf ein double geben und alles was man kriegt ist eine Warnung. In C++ wäre das ein Fehler und ohne Cast compiliert der Code nicht. Ich nehme aber an, dass du das eh schon wusstest.



  • sebi707 schrieb:

    Der compiliert aufgrund der laxen Konvertierungsregeln in C. In C kann ich einer Funktion, die ein Pointer auf ein int akzeptiert, auch ein Pointer auf ein double geben und alles was man kriegt ist eine Warnung. In C++ wäre das ein Fehler und ohne Cast compiliert der Code nicht. Ich nehme aber an, dass du das eh schon wusstest.

    Ah, danke für die Erklärung. Und nein, wusste ich nicht mehr 😉 (Also dass es in C++ ohne Cast nicht geht schon, darum ja die Frage - dass es in C implizit geht *brrr,schüttel* aber nicht.)

    Bleibt für mich aber immer noch die Frage warum das keine strict aliasing Verletzung sein soll. Bin mir nämlich ziemlich sicher dass es wohl eine ist.



  • sebi707 schrieb:

    Der compiliert aufgrund der laxen Konvertierungsregeln in C. In C kann ich einer Funktion, die ein Pointer auf ein int akzeptiert, auch ein Pointer auf ein double geben und alles was man kriegt ist eine Warnung.

    lol.
    Wie niedlich.
    Kommt vor, wenn sich C-Laien über C-Interna unterhalten und in C++ sowas dann regelmäßig wegcasten in der Meinung, so das Problem gelöst zu haben.



  • Wutz schrieb:

    lol.
    Wie niedlich.
    Kommt vor, wenn sich C-Laien über C-Interna unterhalten und in C++ sowas dann regelmäßig wegcasten in der Meinung, so das Problem gelöst zu haben.

    Dann kläre uns bitte auf. Bisher hast du noch keine der Behauptungen zufriedenstellend erklärt. Immer nur auf meiner/unserer Unwissenheit rumzuhaken führt zu nichts.



  • @Wutz
    Nein, in C++ castet man das nicht weg, denn in C++ verwendet man solche Dinge normalerweise einfach nicht. U.a. schon deswegen weil sie meistens eine Strict Aliasing Verletzung darstellen, womit man dann UB hat.

    Kannst du auch begründen was du schreibst? Denn "ich kenn mich voll gut aus und ihr seid alle dumme Noobs" (sinngemäss) ist keine Begründung oder Erklärung. Nur falls dir das nicht klar sein sollte.



  • Also, mit meinem Halbwissen würde ich auch vermuten, dass es die strict aliasing Regel nicht verletzt. Ich bin aber kein Standard-Auswendiglerner, mich würde auch mal eine genauere Erklärung (oder Link) interessieren.



  • Nicht?
    Wieso nicht?

    Es wurde ein Objekt als SubStruct1* , SubStruct2* bzw. SubStruct3* geschrieben, wird dann aber als T* gelesen.
    Wenn das keine Strict-Aliasing Verletzung sein soll, dann würde mich doch sehr interessieren wieso nicht.



  • Wie gesagt, Halbwissen. Strict aliasing gilt für unterschiedliche Typen. Und ich meine "int" und "struct {int x;};" sind in dem Kontext als gleiche Typen definiert.

    Ich hätt sowas aber nicht selber geschrieben, da ich mir nicht ansatzweise sicher bin. Kann man vielleicht aber auch mal einsetzen, wenn das mal jemand richtig erklärt ^^



  • Den int sehe ich ja nicht als Problem, die Zeiger unterschiedlichen Typs dagegen schon.



  • Sorry, ich hab den zweiten Beitrag von Wutz übersehen und bezog mich auf den ersten. Den zweiten versteh ich auch nicht so wirklich.


Anmelden zum Antworten