Sie könnten es tatsächlich so werfen (mit Zeigern)
Vector3d *vector = (Vector3d*) &acceleration;
aber das steht nicht in den Spezifikationen und daher hängt das Verhalten vom Compiler, der Laufzeit und dem großen Grünflächenmonster ab.
+1: Gute Antwort. Beschreibt sowohl die einzige Methode, die garantiert funktioniert, als auch die Methode, die normalerweise in der Praxis funktioniert, und den Grund, warum diese Methode technisch nicht definiert ist.
– Oliver Charlesworth
22. Oktober 2010 um 11:18 Uhr
+1 Ich würde nur hinzufügen, dass die Casting-Technik ziemlich verbreitet ist – es ist nicht so, als wäre es wirklich böse.
– Prof. Falken
22. Oktober 2010 um 11:41 Uhr
+1 zum Einpacken in eine Funktion. Selbst für so etwas Triviales lohnt es sich, eine Unterroutine zu erstellen.
– Alesplin
22. Oktober 2010 um 15:43 Uhr
Was passiert, wenn wir CMAcceleration deklarieren als struct { Vector3d vec; };? Dann haben CMAcceleration-Instanzen zuerst Vector3d sizeof(Vector3d) Byte. Würde das striktes Aliasing beim Pointer-Casting beseitigen?
– holgac
11. April 2015 um 9:03 Uhr
Dann müssten wir keine Zeiger mehr werfen. Wir konnten einfach direkt zuordnen vector = acc.vec;.
– Hermann Döppes
9. Januar 2016 um 10:40 Uhr
Sie könnten einen Zeiger verwenden, um die Typumwandlung durchzuführen;
vector = *((Vector3d *) &acceleration);
Es sei darauf hingewiesen, dass der Compiler nicht verpflichtet ist, dafür zu sorgen, dass beide Structs gleich gepackt und ausgerichtet sind.
@Secure Das ist eine Schande, weil ich diese Technik verwenden möchte, um eine Struktur nicht zu kopieren, sondern tatsächlich zu aliasieren (den Typ zu ändern).
– Michael
22. Oktober 2014 um 2:40 Uhr
@Michael: Geben Sie an, dass bei Verwendung von gcc oder clang der Code mit kompiliert werden muss -fno-strict-aliasing flag (andere Compiler verwenden möglicherweise ein Flag mit demselben Namen oder sind weniger aggressiv in ihren Aliasing-Optimierungen als gcc oder clang).
– Superkatze
12. September 2017 um 14:58 Uhr
groovingandi
memcpy(&vector, &acceleration, sizeof(Vector3d));
Bitte beachten Sie, dass dies nur funktioniert, wenn das physikalische Layout der Strukturen im Speicher identisch ist. Wie @Oli darauf hingewiesen hat, ist der Compiler jedoch nicht verpflichtet, dies sicherzustellen!
Es sei darauf hingewiesen, dass der Compiler nicht verpflichtet ist, dafür zu sorgen, dass beide Structs gleich gepackt und ausgerichtet sind.
– Oliver Charlesworth
22. Oktober 2010 um 11:17 Uhr
@Oli Charlesworth: Du hast Recht und ich habe die Antwort entsprechend aktualisiert
– groovingandi
22. Oktober 2010 um 11:33 Uhr
@OliverCharlesworth: Es würde einen pathologisch perversen Compiler brauchen, um diese Annahme zu brechen, besonders. unter Berücksichtigung der akzeptierten Antwort auf diese Frage: stackoverflow.com/questions/19804655/…
– chqrlie
12. September 2017 um 19:46 Uhr
@chqrlie Die von Ihnen verlinkte akzeptierte Antwort besagt nur, dass ein Compiler sicherstellen muss, dass das Layout gleich ist, wenn beide Strukturen als Teil derselben Vereinigung verwendet werden. Aber es sagt nichts darüber aus, dass Strukturen außerhalb eines Union-Kontexts verwendet werden. So kann ein Compiler in einem Union-Fall ein gleiches Layout erzwingen, da er gemäß Standard, aber in anderen Fällen aufgrund einer seltsamen plattformspezifischen Optimierung beispielsweise unterschiedliche Layouts auswählen muss.
In diesem Fall vector = acceleration; lässt sich prima kompilieren.
Ich bekomme ein warning: 'typedef struct Vector3d Vector3d' does not refer to the unqualified type, so it is not used for linkage. Auch in diesem Fall CMAcceleration befindet sich in einem schwach verknüpften Framework, daher verzichte ich darauf, es in meiner .h-Datei zu verwenden.
– Ortwin Gentz
22. Oktober 2010 um 11:50 Uhr
Wenn die CMAcceleration struct aus einem separaten Framework stammt, sollten Sie am besten die Feld-für-Feld-Kopie anstelle der Memcpy- oder Tippspiel-Tricks durchführen, um Ihren Code für den Fall zukünftiger Änderungen im anderen Framework robust zu machen. (Auch wenn Sie wissen, dass die Strukturlayouts heute identisch sind, werden sie in späteren Versionen möglicherweise nicht so bleiben.)
Ich bekomme ein warning: 'typedef struct Vector3d Vector3d' does not refer to the unqualified type, so it is not used for linkage. Auch in diesem Fall CMAcceleration befindet sich in einem schwach verknüpften Framework, daher verzichte ich darauf, es in meiner .h-Datei zu verwenden.
– Ortwin Gentz
22. Oktober 2010 um 11:50 Uhr
Wenn die CMAcceleration struct aus einem separaten Framework stammt, sollten Sie am besten die Feld-für-Feld-Kopie anstelle der Memcpy- oder Tippspiel-Tricks durchführen, um Ihren Code für den Fall zukünftiger Änderungen im anderen Framework robust zu machen. (Auch wenn Sie wissen, dass die Strukturlayouts heute identisch sind, werden sie in späteren Versionen möglicherweise nicht so bleiben.)
– David Gelhar
22. Oktober 2010 um 13:03 Uhr
Lundklinge
Eine andere Version der Hilfsfunktion, die C99 verwendet:
Können Sie nicht einfach typedef (z. B. typedef struct CMAcceleration Vector3d) eingeben? Ups, da hatte ja schon jemand darauf hingewiesen…
– Nyan
22. Oktober 2010 um 11:37 Uhr