2012-04-04 15 views
2

Könnte mir bitte jemand sagen, warum ist die Assert fehlgeschlagen?bitfields funktioniert nicht wie erwartet in einer Union

FYI: Ich kompiliere dies mit gcc 4.6.1 auf einem 64-Bit-Linux-Rechner.

typedef union cpu_register { 
    uint64 _64; 
    uint32 _32; 
    uint16 _16; 
    uint16 _8l : 8, 
      _8h : 8; 
} __attribute__((packed)) cpu_register; 

int main() 
{ 
    cpu_register reg; 
    reg._64 = 1; 
    assert(reg._8h != reg._8l); 
    return 0; 
} 

Der Wert für reg._8h erwarten ist 0, aber es ist gleich der reg._8l (== 1).

Ich habe eine Lösung, um dieses Problem zu überwinden, aber ich möchte wissen, was los ist?

+0

Bitte fügen Sie Ihrer Frage ein Sprach-Tag (C?) Hinzu, es wird Menschen helfen, Ihre Frage zu finden und die richtige Lösung zu bieten. – aKzenT

+0

yup seine C-Sprache, tut mir leid, es war mein erster Beitrag, also habe ich es verpasst. – user1314006

Antwort

3

Es sieht aus wie Sie

uint16 _8l : 8, 
     _8h : 8; 

wollten die niedrigen und hohen Bits eines 16-Bit-Integer sein.

Aber diese sind in einer Vereinigung, und jedes Element einer Vereinigung in-Effekt steht für die gesamte Union. Sie beziehen sich also jeweils auf die gleichen 8 Bits.

Sie müssen sie in einer Struktur wickeln:

struct { 
    uint16 _8l : 8, 
      _8h : 8; 
} 

und dann in die Union diese Struktur setzen.

+0

Ja, ich habe die Struktur verwendet, um das zu beheben. Ich habe was du sagen willst. Vielen Dank. – user1314006

+0

Richtig, um zu verdeutlichen: Was schief gelaufen ist, dass du du Uint16 _8l: 8; uint16 _8h: 8; in einer Gewerkschaft. Wenn zwei Variablen in einer Vereinigung sind, beziehen sie sich auf die gleichen Daten, d. H. Auf dieselben 8 Bits. Zwei Variablen in einer Struktur beziehen sich auf unterschiedliche Daten (normalerweise nebeneinander). – Max

+0

Nochmals vielen Dank. – user1314006