Was ist C ++ struct Syntax „a: b“ bedeuten
-
05-07-2019 - |
Frage
Wenn ich eine C ++ Struktur, die ein 64-Bit-Datenwort wie ..
struct SMyDataWord
{
int Name : 40;
int Colour : 24;
};
Was bedeutet die : 40
Syntax ... bedeutet es, dass die ersten 40 Bits für den Namen und die restlichen 24 Bits für die Farbe reserviert sind?
Dies ist, wie es scheint, verwendet werden wird, aber ich habe vor über es nicht kommen.
Lösung
Bitfelder, von C. Name
übertragen ist 40 Bit breit, Colour
ist 24 Bit breit. Ihre Struktur hat daher mindestens 64 Bit. Auf meinem System würden 64 Bits 8 Bytes sein.
Andere Tipps
Ja, das ist die Syntax für bitfields . Sie werden häufig definieren structs verwendet, die auf Hardware-Registern zugeordnet werden. Es gibt einige Dinge im Auge zu behalten, wenn Sie sie verwenden entscheiden, ist eine, die Sie nicht wissen können, wie der Compiler tut das Layout, die Bestellung und Polsterung in den tatsächlichen Bytes die Felder bilden können und unter Compiler unterscheiden (und vielleicht mit dem gleichen Compiler, aber mit unterschiedlichen Optimierungseinstellungen, auch).
Das ist eine Bitfeld Definition.
Name ist eine ganze Zahl, die genau 40 Bits an Informationen zu speichern, ist in der Lage. Farbe kann 24 Bits speichern.
Dies ist oft getan, um Platz zu sparen in oft benötigten Strukturen oder Code komprimieren bis zu einer Größe, die für die CPU (in Ihrem Fall 64 Bits. Fit genau in ein CPU-Register auf einem 64-Bit-Maschine) einfach zu handhaben ist.
Der Code, der die bitfields zugreift wird allerdings etwas langsamer ausgeführt werden.
Denken Sie daran, dass fast alles über Bit-Felder ist die Umsetzung abhängig. Zum Beispiel, ob Bits gespeichert sind, von links nach rechts oder von rechts nach links, hängt von der tatsächlichen Hardware-Architektur. Außerdem, jeder Compiler verwendet ein anderes Mitglied Ausrichtung Modell, weshalb die Größe des optimierten BillingRec 12 Bytes statt 9. Sie können nicht nehmen ein Bit-Feld die Adresse noch können Sie erstellen ein Array von Bits. Schließlich, am meisten Implementierungen die Verwendung von Bitfeldern entstehen Kopfgeschwindigkeit. Wenn daher Sie Ihren Code optimieren, messen die Wirkung einer bestimmten Optimierung und seine Vor- und Nachteile, bevor Sie sich entscheiden, zu verwenden, es.
Hier sizeof
schön zeigt, was unter der Haube vor sich geht:
#include <iostream>
#include <climits>
struct bc_1 {
int a : 1;
int b : 1;
};
struct bc_2 {
int a : 31;
int b : 1;
};
struct bc_3 {
int a : 32;
int b : 1;
};
struct bc_4 {
int a : 31;
int b : 2;
};
struct bc_5 {
int a : 32;
int b : 32;
};
struct bc_6 {
int a : 40;
int b : 32;
};
struct bc_7 {
int a : 63;
int b : 1;
};
int main(int argc, char * argv[]) {
std::cout << "CHAR_BIT = " << CHAR_BIT;
std::cout << " => sizeof(int) = " << sizeof(int) << std::endl;
std::cout << "1, 1: " << sizeof(struct bc_1) << std::endl;
std::cout << "31, 1: " << sizeof(struct bc_2) << std::endl;
std::cout << "32, 1: " << sizeof(struct bc_3) << std::endl;
std::cout << "31, 2: " << sizeof(struct bc_4) << std::endl;
std::cout << "32, 32: " << sizeof(struct bc_5) << std::endl;
std::cout << "40, 32: " << sizeof(struct bc_6) << std::endl;
std::cout << "63, 1: " << sizeof(struct bc_7) << std::endl;
}
Was folgt, hängt von Ihrem Compiler und Betriebssystem und möglicherweise auf Ihrer Hardware. Auf macOS mit gcc-7 (mit einer CHAR_BIT
= 8 ist, ein 32-Bit int
(das heißt die Hälfte der 64-Bit-long
) sizeof(int)
= 4 hat), ist dies die Ausgabe-I zu sehen:
CHAR_BIT = 8 => sizeof(int) = 4
1, 1: 4
31, 1: 4
32, 1: 8
31, 2: 8
32, 32: 8
40, 32: 12
63, 1: 8
Das sagt uns mehrere Dinge: wenn beide Felder von int
Typ passen in einen einzigen int
(das heißt 32 Bits in dem obigen Beispiel), der Compiler nur eine einzige int
im Wert von Speicher (bc_1
und bc_2
) zuordnet. Einmal kann ein einzelner int
nicht die bitfields mehr halten, fügen wir einen zweiten (bc_3
und bc_4
). Beachten Sie, dass bc_5
an Kapazität.
Interessanterweise können wir „die Option“ mehr Bits als erlaubt. Siehe bc_6
. Hier g ++ - 7 gibt eine Warnung aus:
bitfields.cpp::30:13: warning: width of 'bc_6::a' exceeds its type
int a : 40;
^~
Beachten Sie, dass: Klirren ++ erklärt dies in einem besseren Detail
bitfields.cpp:30:9: warning: width of bit-field 'a' (40 bits) exceeds the width of its type; value will be truncated to 32 bits [-Wbitfield-width]
int a : 40;
^
Allerdings scheint es, dass unter der Haube, der Compiler im Wert eines anderen int
von Speicher reserviert. Oder zumindest, bestimmen sie die richtige Größe. Ich denke, der Compiler uns warnt, nicht auf diesen Speicher als int a = bc_6::a
zuzugreifen (Ich würde das int a
Wette würde dann nur die ersten 32 Bit des Feldes bc_6::a
haben ...). Dies wird durch bc_7
, deren Gesamtgröße bestätigt ist, dass von zwei int
s, aber der erste Bereich betrifft, die meisten von ihnen.
Schließlich ersetzt int
mit long
in dem obigen Beispiel verhält sich wie erwartet:
CHAR_BIT = 8 => sizeof(long) = 8
1, 1: 8
31, 1: 8
32, 1: 8
31, 2: 8
32, 32: 8
40, 32: 16
63, 1: 8