Unterschiedliche Strukturnamen mit gleichem Inhalt (optimale Funktionsübergabe?)
-
SBond schrieb:
Muss gestehen, dass ich mit der Zeile "setValue( (t.s1=&x.s1,&t), 1);" noch so meine Verständnisprobleme habe.
Tja, was soll man da machen?
2 Hinweise mit lauffähigen Codes gegeben und du hast es immer noch nicht geschnallt.
Man kann statt einem auch mehrere Objekte spendieren und die dann in deren Scope jederzeit verwenden, und kommt immer noch ohne irgendwelchen Makro- oder Template-Quatsch aus:int main() { MainStruct_t x; printf("%d %d %d\n",x.s1.Value,x.s2.Value,x.s3.Value); { T t1={&x.s1},t2={.s2=&x.s2},t3={.s3=&x.s3}; setValue( &t1, 1); setValue( &t2, 2); setValue( &t3, 3); } printf("%d %d %d\n",x.s1.Value,x.s2.Value,x.s3.Value); return 0; }http://ideone.com/ds0bSP
Das ist nun wirklich auch für C Laien verständlich, wenn du das auch nicht schnallst, such dir ein anderes Hobby.P.S. In jedem Fall musst du sicherstellen, dass das Padding der structs im Fremdmodul das Gleiche wie in deinem eigenen ist.
-
Wutz schrieb:
sebi707 schrieb:
Der Code von Wutz ist auch scheiße.
Du hast keine Ahnung wovon du redest.
Bitte demonstriere deinen Code für structs wo
'int Value;'nicht an erster Stelle steht. Und dann noch als Extra für structs wo Value in allen structs an verschiedenen Stellen steht.
-
hustbaer schrieb:
Zwei Fragen zu deinem Code:
- weil du die Eigenschaft von union bzgl. des Member- und Gesamtzugriffs nicht verstanden hast
- da bin ich mir sehr sicher
Nur weil du den Gebrauch von union nicht verstanden hast musst du nicht davon ausgehen, dass andere das auch nicht verstehen werden bzw. verstanden haben.
Mit dem von mir gezeigten union-Gebrauch kann man komplette vtable-Hierarchien inkl. Mehrfachvererbung in blankem ANSI C nachbilden und das ist in jedem Fall besser als dem Anfänger irgendwelchen Makro/Template-Quatsch an die Hand zu geben und womöglich auch noch dynamic_cast und Konsorten nebst virtual-Quatsch zu zeigen mit dem Hinweis, dass so und nicht anders professionell C++ programmiert wird.
In blankem ANSI C gibts bei solchen Versuchen, innerhalb der vtable-Nachbildung wild rumzucasten dann gleich was vom Compiler auf die Finger und nicht erst zur Laufzeit wie bei den C++-üblichen Unsinns-Casts.
(Den Begriff vtable habe ich jetzt mal zur Veranschaulichung für dich gewählt, damit du einfacher den C-Hintergrund verstehen kannst; der kommt natürlich im C-Sprachgebrauch so nicht vor)
-
Dann erkläre mit bitte union. Ich programmieren zwar schon eine Weile aber vielleicht bin ich ja missinformiert. Für mich beduetet eine union das alle Member der union im gleichen Speicherbereich gespeichert werden. Allerdings hat der Compiler nach meinem Wissen keine Ahnung was für eine Variable ich dort wirklich gerade drin gespeichert habe. Wie man damit virtual Function Calls nachbilden können soll ist mir auch ein Rätsel.
-
-
Wutz schrieb:
- 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; }Beispielausgabe:
47 134513954 3Der 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 alsT*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
intsehe 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.