Doppel-Array in eine Double-Struktur umwandeln

8

Ist es OK, ein Double-Array in eine Double-Struktur umzuwandeln?

%Vor%

Dies druckt 1 2 3 . Aber ist es garantiert immer mit jedem Compiler zu arbeiten?

EDIT: Nach

  

9.2.21: Ein Zeiger auf ein Standard-Layout-Strukturobjekt, passend konvertiert? Mit einem reinterpret_cast zeigt er auf seinen ursprünglichen Member (...) und umgekehrt.

wenn ich meinen Code durch

ersetze %Vor%

dann ist es garantiert zu arbeiten. Richtig? Ich verstehe, dass viele Leute das nicht ästhetisch ansprechend finden würden, aber es gibt Vorteile beim Arbeiten mit einer Struktur und nicht beim Kopieren der Eingangsarraydaten. Ich kann Memberfunktionen in dieser Struktur definieren, um Skalar- und Vektorprodukte, Entfernungen usw. zu berechnen, was meinen Code viel leichter verständlich macht, als wenn ich mit Arrays arbeiten würde.

Wie wäre es mit

? %Vor%

Funktioniert das auch, oder der Compiler könnte etwas NACH den Datenmitgliedern einfügen, so dass sizeof(A) > 3*sizeof(double) ? Und gibt es irgendeine portable Möglichkeit, den Compiler davon abzuhalten?

    
vitke 26.06.2015, 21:26
quelle

6 Antworten

9

Nein, das ist nicht garantiert.

Die einzige Sache, die es einem Compiler verbietet, Füllzeichen zwischen x und y oder zwischen y und z einzufügen, ist normal. Es gibt keine Regel in irgendeinem Sprachstandard, die es verbieten würde.

Auch wenn kein Padding vorhanden ist, auch wenn die Repräsentation von A genau der von double[3] entspricht, ist sie immer noch nicht gültig. Die Sprache erlaubt es Ihnen nicht vorzugeben, dass ein Typ wirklich ein anderer Typ ist. Sie dürfen nicht einmal eine Instanz von struct A { int i; }; behandeln, als wäre es ein struct B { int i; }; .

    
hvd 26.06.2015 21:34
quelle
2

Der Standard gibt wenig Garantien über das Speicherlayout von Objekten.

Für Klassen / Strukturen:

  

9.2./15: Nichtstatic-Datenelemente einer Klasse mit derselben Zugriffssteuerung werden zugewiesen, sodass spätere Mitglieder höhere Adressen haben   innerhalb eines Klassenobjekts. Die Reihenfolge der Zuweisung von nicht statischen Daten   Mitglieder mit unterschiedlicher Zugriffskontrolle sind nicht spezifiziert. Implementierung    Alignment-Anforderungen können dazu führen, dass zwei benachbarte Member nicht unmittelbar hintereinander zugeordnet werden ; so könnte Anforderungen für   Platz für die Verwaltung virtueller Funktionen und virtueller Basisklassen.

Bei Arrays sind die Elemente zusammenhängend. Zur Ausrichtung wird nichts gesagt, daher kann es dieselben Ausrichtungsregeln wie in struct verwenden oder auch nicht:

  

8.3.4: Ein Objekt vom Typ Array enthält eine zusammenhängend zugeordnete, nicht leere Menge von N Unterobjekten vom Typ T.

Das Einzige, was Sie in Ihrem speziellen Beispiel sicher wissen können, ist, dass a.x arr[0] entspricht, wenn Sie eine reinterpret_cast verwenden:

  

9.2.21: Ein Zeiger auf ein Standard-Layout-struct-Objekt, das mit einem reinterpret_cast entsprechend konvertiert wurde, zeigt auf seinen ursprünglichen Member (...)   und umgekehrt. [
  & gt;

    
Christophe 26.06.2015 21:57
quelle
1

Nach allem, was ich weiß, lautet die Antwort: ja.

Das einzige, was Sie abweisen könnte, ist eine # pragma-Direktive mit einigen sehr ungewöhnlichen Ausrichtungseinstellungen für die Struktur. Wenn zum Beispiel ein Double 8 Bytes auf Ihrem Rechner benötigt und die #pragma-Anweisung sagt, dass jedes Member an 16-Byte-Grenzen ausgerichtet werden soll, die Probleme verursachen könnten. Ansonsten geht es dir gut.

    
nv3 26.06.2015 21:35
quelle
1

Nein, es ist nicht garantiert, selbst wenn es mit allen Compilern funktionieren sollte, die ich auf einer gemeinsamen Architektur kenne, weil die C-Spezifikation sagt:

6.2.6 Repräsentationen von Typen 6.2.6.1 Allgemein1 Die Darstellungen aller Typen sind nicht spezifiziert, außer wie in dieser Unterklausel angegeben. Und es sagt nichts über das Standard-Padding in einer Struktur aus.

Natürlich verwenden gängige Architekturen höchstens 64 Bit, was der Größe eines Double auf dieser Architektur entspricht. Daher sollte es keine Auffüllung geben und die Konvertierung sollte funktionieren.

Aber Vorsicht : Sie rufen explizit Undefined Behavior auf, und die nächste Generation von Compilern könnte alles bei der Erstellung eines solchen Cast machen.

    
Serge Ballesta 26.06.2015 21:41
quelle
0

std :: komplexe Implementierung von msvc verwendet die Array-Lösung und llvm libc ++ verwendet das vorherige Formular.

Ich denke, überprüfen Sie einfach die Implementierung des std :: -Komplexes Ihrer libc ++ und verwenden Sie die gleiche Lösung damit.

    
Yongjian Wang 05.04.2018 04:44
quelle
-2

Ich stimme hier nicht überein. Eine Struktur mit drei Doubles ist genau dasselbe wie ein Array mit 3 Doubles. Es sei denn, Sie packen die Struktur speziell anders und befinden sich auf einem komischen Prozessor, der eine ungerade Anzahl von Bytes für Doppel hat.

Es ist nicht in die Sprache integriert, aber ich würde mich dabei sicher fühlen. Stilweise würde ich es nicht tun, weil es nur verwirrend ist.

    
iplayfast 26.06.2015 21:48
quelle