2016-07-05 6 views
6

Ich bin auf viele Fragen zu Bitfeldern gestoßen, die behaupten, dass Bitfelder nicht portabel sind, aber ich habe nie eine Quelle gefunden, die genau erklärt warum.Warum und wie sind C++ - Bitfelder nicht portierbar?

Bei Nennwert hätte ich angenommen, dass alle Bitfelder lediglich zu Variationen des gleichen Bitshifting-Codes kompilieren, aber offensichtlich muss es auch mehr geben, sonst würde es keine so heftige Abneigung für sie geben.

Also meine Frage ist was macht Bitfields nicht tragbar?

+1

In welchem ​​Kontext wurden sie "unsicher" genannt? Einen Link hinzufügen? – anatolyg

+6

Ich denke, es ist hauptsächlich, wie Leute Bitfields missbrauchen, um Teile anderer Datentypen-Repräsentationen auf Sub-Byte-Ebenen zu extrahieren, was komplett nicht portabel ist. – user2357112

+0

@anatolyg [Lundins Kommentar] (http://stackoverflow.com/questions/35934375/bitfields-in-c-programming-language/35935493#comment59526628_35934375) auf [diese Frage] (http://stackoverflow.com/questions/ 35934375/bitfields-in-c-Programmiersprache/35935493). Zugegeben, ich habe nicht gesehen, dass sie genauso beschuldigt werden, "unsicher" zu sein, wie ich "nicht tragbar" habe, aber trotzdem. – Pharap

Antwort

2

Bitfelder sind nicht portierbar in dem Sinne, dass die Reihenfolge des Bits nicht spezifiziert ist. So könnte das Bit bei Index 0 mit einem Compiler sehr gut das letzte Bit mit einem anderen Compiler sein.

Dies verhindert die Verwendung von Bitfeldern in Anwendungen wie dem Umschalten von Bits in speicherplatzierten Hardwareregistern.

Aber Sie werden sehen, Hardware-Anbieter Bitfelder in dem Code verwenden sie freigeben (wie Mikrochip zum Beispiel). Üblicherweise liegt es daran, dass sie den Compiler damit auch freigeben oder einen einzelnen Compiler targetieren. Im Fall von Mikrochips beispielsweise verlangt die Lizenz für ihren Quellcode, dass sie ihren eigenen Compiler verwenden (für 8-Bit-Low-End-Geräte).

Der Link, auf den @Pharap zeigt, enthält einen Auszug aus dem (C++ 14) Norm bezogen auf diese nicht spezifizierte Bestellung: is-there-a-portable-alternative-to-c-bitfields

+2

Dieses Bitfeldlayout ist implementationsdefiniert, macht Bitfelder nicht tragbar. Es ist der Code, der ein bestimmtes Layout annimmt, das nicht tragbar ist. – 4386427

+0

@ 4386427: Der allgemeine Grund * für die Verwendung von Bitfeldern besteht darin, ein gewünschtes Layout zu erhalten, z. Optionsbits in einem Argument für eine OS-API-Funktion. Das Problem ist, dass nicht alle Compiler dasselbe Ergebnis liefern können (oder anders ausgedrückt, dass der Standard keine vernünftigen Garantien für den häufigsten Anwendungsfall bietet). Am Ende ist jemand eingeschraubt, aber nicht unbedingt der ursprüngliche Programmierer. –

+0

@ 4386427 Ein Sprachkonstrukt ist nicht tragbar oder nicht tragbar. Es wird von einem Compiler unterstützt oder nicht. Wenn wir von Portabilität sprechen, sprechen wir immer über die * Verwendung * dieser Konstrukte. Ich hielt es nicht für nötig, das zu präzisieren. – fjardon

8

Bit-Felder sind nicht portierbar im gleichen Sinne wie Integer nicht tragbar sind. Sie können Ganzzahlen verwenden, um ein tragbares Programm zu schreiben, aber Sie können nicht erwarten, eine binäre Darstellung von int wie auf einem Remote-Computer zu senden und erwarten, dass es die Daten richtig interpretiert.

Dies liegt daran, dass 1. Wortlängen von Prozessoren unterscheiden, und deshalb die Größen von Integer-Typen unterscheiden (1,1 Byte Länge kann auch abweichen, aber das ist heutzutage selten außerhalb eingebetteter Systeme). Und weil 2. die Byte-Endianess über die Prozessoren hinweg unterschiedlich ist.

Diese Probleme sind leicht zu überwinden. Native Endiannität kann leicht in die vereinbarte Endianz umgewandelt werden (Big Endian ist de facto Standard für die Netzwerkkommunikation), und die Größe kann zur Kompilierzeit inspiziert werden, und Integer-Typen fester Länge sind heutzutage verfügbar. Daher können ganze Zahlen verwendet werden, um über das Netzwerk hinweg zu kommunizieren, solange diese Details beachtet werden.

Bitfelder, die auf regulären Integer-Typen aufbauen, haben also dieselben Probleme mit der Endian- und Integer-Größe. Aber sie haben even more Implementierung spezifiziertes Verhalten.

  • Alles über die tatsächliche Zuteilung Details von Bitfeldern innerhalb der Klasse Objekt

    • Zum Beispiel auf einigen Plattformen Bitfelder Bytes nicht überspannen, auf andere sie tun
    • Auf einigen Plattformen sind Bitfelder auch von links nach rechts gepackt, andere von rechts nach links.
  • Ob cha r, short, int, long und long long Bitfelder, die nicht explizit signiert oder vorzeichenlos sind, sind signiert oder unsigniert.

Im Gegensatz zu endianness ist es nicht trivial „alles über die tatsächliche Zuteilung“ oder auf eine kanonische Form zu konvertieren.

Auch während Endianness CPU-Architektur ist, sind die Bitfelddetails spezifisch für den Compilerimplementierer. Bit-Felder sind also nicht für die Kommunikation zwischen verschiedenen Prozessen innerhalb desselben Computers übertragbar, es sei denn, wir können garantieren, dass sie mit demselben (Version von) Compiler kompiliert wurden.


TL, DR-Bitfelder sind keine portable Möglichkeit, zwischen Computern zu kommunizieren. Ganzzahlen sind es auch nicht, aber ihre Nicht-Portabilität ist einfach zu umgehen.

Verwandte Themen