Hva gjør C ++ struct syntaks "a: b" betyr

stemmer
21

Hvis jeg har en C ++ struct, som definerer en 64bit data ord som ..

struct SMyDataWord
{
    int Name : 40;
    int Colour : 24;
};

Hva gjør : 40syntaks mener ... betyr det at de første 40 biter er reservert for navn og de resterende 24 bits for Color?

Dette er hvordan det ser ut til å bli brukt, men jeg har ikke kommet over det før.

Publisert på 05/05/2009 klokken 10:36
kilden bruker
På andre språk...                            


5 svar

stemmer
18

Bitfields, overført fra C Nameer 40 biter brede, Colourer 24 bits bred. Din struct har derfor minst 64 bits. På mitt system 64 bits ville være 8 byte.

Svarte 05/05/2009 kl. 10:39
kilden bruker

stemmer
7

Ja, det er syntaksen for bitfields . De er ofte brukt til å definere structs som kart på maskinvareregistre. Det er noen ting å huske på hvis du velger å bruke dem, er en som du ikke kan vite hvordan kompilatoren gjør oppsettet, bestilling og polstring i selve bytes som utgjør feltene kan og vil variere blant kompilatorer (og kanskje med samme kompilatoren, men med ulike optimaliseringsinnstillingene, også).

Svarte 05/05/2009 kl. 10:40
kilden bruker

stemmer
6

Det er en bitfield definisjon.

Navnet er et helt tall som er i stand til å lagre nøyaktig 40 biter av informasjon. Farge kan lagre 24 biter.

Dette er ofte gjort for å spare litt plass i ofte trengs strukturer, eller komprimere kode ned til en størrelse som er lett å håndtere for CPU (i ditt tilfelle 64 bits. Fits nøyaktig inn en CPU register på en 64 bit maskin).

Koden som har tilgang til bitfields vil utføre en litt langsommere skjønt.

Svarte 05/05/2009 kl. 10:40
kilden bruker

stemmer
3

Bruk dem judiciously :

Husk at nesten alt om bits felt er gjennomføringen avhengig. For eksempel, om bits lagres venstre mot høyre eller fra høyre mot venstre avhenger av det aktuelle maskinvarearkitektur. Videre har hver kompilatoren bruker et annet medlem justering modellen, som er grunnen til at størrelsen på den optimaliserte BillingRec er 12 bytes i stedet for 9. Du kan ikke ta en bit felt adresse du kan heller ikke opprette en matriser av biter. Til slutt, på de fleste implementeringer bruk av bits felt pådrar hastighet overhead. Derfor, når du optimalisere koden din, måle effekten av en viss optimalisering og dens avveininger før du bestemmer deg for å bruke den.

Svarte 05/05/2009 kl. 10:51
kilden bruker

stemmer
0

Her sizeofpent demonstrerer hva som skjer under panseret:

#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;
}

Det som følger er avhengig av kompilatoren og OS, og muligens på maskinvaren. På Macos med gcc-7 (med en CHAR_BIT= 8, et 32 bit int(dvs. halvparten av 64 bit long) har sizeof(int)= 4) Dette er utgangen jeg ser:

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

Dette forteller oss flere ting: hvis begge felt av inttypen passe inn i en enkelt int(dvs. 32 biter i eksempelet ovenfor), tildeler kompilatoren bare én inter verdt minne ( bc_1og bc_2). Når en enkelt intkan ikke holde bitfields lenger, legger vi en andre ( bc_3og bc_4). Legg merke til at bc_5er på kapasitet.

Interessant, kan vi "velg" flere bits enn tillatt. Se bc_6. Her g ++ - 7 gir en advarsel:

bitfields.cpp::30:13: warning: width of 'bc_6::a' exceeds its type
     int a : 40;
             ^~

Merk at: klang ++ forklarer dette i bedre detalj

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;
    ^

Men det virker som under panseret, tildeler kompilatoren annet inter verdt minne. Eller i det minste, bestemmer den riktige størrelse. Jeg antar kompilatoren advarer oss ikke å få tilgang til dette minnet som int a = bc_6::a(jeg ville satse på at int ada ville bare ha de første 32 biter av felt bc_6::a...). Dette bekreftes av bc_7hvis totale størrelse er det av to ints, men det første felt dekker de fleste av dem.

Endelig erstatte intmed longi eksempelet ovenfor oppfører seg som forventet:

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
Svarte 08/04/2018 kl. 20:51
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more