Bitfeld in Struct in Union

Gast #1334142
HI,

ich habe eine Frage zum Thema Bitfeld in Struct in Union.

Es geht mir dabei um einen Datentyp bestehend aus 8 Bits, welche man 
entweder gemeinsam oder einzeln ansprechen können soll.

Ich würde in meinem Programm gern folgendes schreiben können:


typedef struct
{
    uint8_t    bit0:1,
               bit1:1,
               bit2:1,
               bit3:1,
               bit4:1,
               bit5:1,
               bit6:1,
               bit7:1,
}meintyp;


void func1 (meintyp a)
{


}


void main (void)
{
    uint8_t   zahl=0;
    meintyp_t a;

    a=4;
    a=zahl;
    a.bit0=1;
    a.bit1=1;

    func1(a);
    func1(23);
}



Wie kann ich das lösen?

Wenn ich es so gestalte:


typedef union
{
    uint8_t    byte;
    uint8_t    bit0:1,
               bit1:1,
               bit2:1,
               bit3:1,
               bit4:1,
               bit5:1,
               bit6:1,
               bit7:1,
    }bits;
}meintyp;

dann müsste ich doch:

void main (void)
{
    uint8_t   zahl=0;
    meintyp_t a;

    a.byte=4;
    a.byte=zahl;

    a.bit0=1;
    a.bit1=1;

    ....
}

schreiben oder!?

Gruß,
Hannes
#1334177
1
typedef union
2
{
3
  uint8_t    byte;
4
  struct
5
  {
6
    unsigned      bit0:1;
7
    unsigned      bit1:1;
8
    unsigned      bit2:1;
9
    unsigned      bit3:1;
10
    unsigned      bit4:1;
11
    unsigned      bit5:1;
12
    unsigned      bit6:1;
13
    unsigned      bit7:1;
14
      };
15
} meintyp_t;
16

17
int main (void)
18
{
19
    uint8_t   zahl=0;
20
    meintyp_t a;
21

22
    a.byte=4;
23
    a.byte=zahl;
24

25
    a.bit0=1;
26
    a.bit1=1;
27
    return 0;
28
}
#1334207
Wenn du unsigned weglässt, geht gar nichts mehr, weil der Typ fehlt.
Lässt du nur das un weg und machst dann folgendes:
1
    a.bit1=1;
2
    printf( "%d\n", a.bit1 );
.. kommt das raus:
1
klaus@i4a:~ > gcc -Wall t.c && ./a.out
2
-1

Alle gesetzten Bit in einer signed sind offenbar wie üblich -1 :-))

Je nach Fall ist es egal, ein Bit wird man eh nur auf gleich oder 
ungleich 0 testen.
Ein Vergleich mit 1 wird aber lustige Folgen haben.
Persönliche Seite #1334511
Klaus Wachtler schrieb:
>
1
> typedef union
2
> {
3
>   uint8_t    byte;
4
>   struct
5
>   {
6
>     unsigned      bit0:1;
7
>     unsigned      bit1:1;
8
>     unsigned      bit2:1;
9
>     unsigned      bit3:1;
10
>     unsigned      bit4:1;
11
>     unsigned      bit5:1;
12
>     unsigned      bit6:1;
13
>     unsigned      bit7:1;
14
>       };
15
> } meintyp_t;
16
>

Anonyme struct members sind zwar äußerst praktisch, aber leider nicht
standardkonform und werden daher nicht von allen Compilern
unterstützt. GCC und ARM RealView (mit entsprechendem #pragma)
erlauben dieses Konstrukt.

Gruß
Marcus
http://www.doulos.com/arm/
Gast #1335024
@Hallo KLaus,

danke für die Rückmeldung doch mein eigentliches Problem kommt erst 
noch.

@Marcus Harnisch,
das ist in diesem Fall ohne Folge da ich keinen datenaustausch auf 
unterschiedlichen Architekturen ausführen werde und keine 
unterschiedlichen Kompiler nutze, und der Code nur auf einem Prozessor 
laufen wird. Zumal das ganze nur zur internen Verwaltung innerhalb eines 
geschachtelten abgeschlossenen c Objektes zum Einsatz kommt.

1)
fehlt vor den bits des bitfeldes nicht der typ, oder ist unvollständig? 
oder geht das, weil es eine union ist? das sieht komisch aus.

2)
soweit das ich das schreiben kann:

    uint8_t   zahl=0;
    meintyp_t a;

    a.byte=4;
    a.byte=zahl;

    a.bit0=1;
    a.bit1=1;
    return 0;

war ich schon, nur ich würde das gern so schreiben können:

void func1 (meintyp a)
{


}


void main (void)
{
    uint8_t   zahl=0;
    meintyp_t a;

    a=4;
    a=zahl;
    a.bit0=1;
    a.bit1=1;

    func1(a);
    func1(23);
}

ohne das .byte wenn ich einen 8bit wert zuweise, und wenn eine Funktion 
diesen typ als übergabetyp hat, dann würde ich sie gern wie oben 
aufgezeigt aufrufen können - geht das?

die 23 kann nicht zugewiesen werden, wie bekomme ich das hin, ohne 
vorher auf das "objekt" zu zeigen, von hinten durch die brust. Cast 
schlägt auch fehl...deswegen ja die Geschichte mit der union...

Gruß,
Hannes
#1335047
Hannes schrieb:
> ...
> 1)
> fehlt vor den bits des bitfeldes nicht der typ, oder ist unvollständig?
> oder geht das, weil es eine union ist? das sieht komisch aus.

unsigned ist ein Typ; du kannst auch unsigned int schreiben, wenn dir 
das lieber ist.

signes ist int ebenso wie signed int, und unsigned ist unsigned int, und
short ist short int etc.

>
> 2)
> soweit das ich das schreiben kann:
>
>     uint8_t   zahl=0;
>     meintyp_t a;
>
>     a.byte=4;
>     a.byte=zahl;
>
>     a.bit0=1;
>     a.bit1=1;
>     return 0;
>
> war ich schon, nur ich würde das gern so schreiben können:
>
> void func1 (meintyp a)
> {
>
>
> }
>
>
> void main (void)
> {
>     uint8_t   zahl=0;
>     meintyp_t a;
>
>     a=4;
>     a=zahl;
>     a.bit0=1;
>     a.bit1=1;
>
>     func1(a);
>     func1(23);
> }
>
> ohne das .byte wenn ich einen 8bit wert zuweise, und wenn eine Funktion
> diesen typ als übergabetyp hat, dann würde ich sie gern wie oben
> aufgezeigt aufrufen können - geht das?

nein.
Bzw. nur mit cast, aber dann kannst du auch .byte schreiben.

>
> die 23 kann nicht zugewiesen werden, wie bekomme ich das hin, ohne
> vorher auf das "objekt" zu zeigen, von hinten durch die brust. Cast
> schlägt auch fehl...deswegen ja die Geschichte mit der union...

nicht in C, in C++ geht es mit Überladen von Operatoren..

>
> Gruß,
> Hannes
#1335051
> typedef union
> {
>   uint8_t    byte;
>   struct
>   {
>     unsigned      bit0:1;
>     unsigned      bit1:1;
>     unsigned      bit2:1;
>     unsigned      bit3:1;
>     unsigned      bit4:1;
>     unsigned      bit5:1;
>     unsigned      bit6:1;
>     unsigned      bit7:1;
>       };
> } meintyp_t;
>

mach mal ein sizeof(meintyp_t).
Meiner meinung nach sollte da eine 4 rauskommen, auch wenn du prgma pack 
verwendest.
da das bitfeld aller wahrscheinlichkeit 32 bit breit ist.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.