2010-06-21 13 views
9

È possibile utilizzare bitfield in unione?c union e bitfield

+12

Quando fanno due cose cattive, si sommano o si moltiplicano? ;-) –

+0

+1 a Amardeep. Non fare e non divya. –

+0

I campi di bit e i campi di Neighter devono essere malvagi. Uso le strutture nei sindacati per analizzare l'input/output di byte nel software incorporato. Il suo comfort sbilancia i suoi svantaggi. – schmijos

risposta

2

Sì, è possibile, ma vorrei raccomandarlo contro. La lunghezza e l'imballaggio dei bitfield non sono portatili. La dimensione dell'unione sarà difficile da prevedere (vedi here). C'è una certa quantità di complessità che introduci nel codice quando usi sindacati o bitfield. Mentre questa complessità può essere accettabile nel tuo codice, combinare i due può portare a una quantità inaccettabile di complessità. Se si utilizzano i sindacati, le strutture e i bitfield, si verificano problemi con l'allineamento della memoria.

Se questo è un codice usa e getta che deve solo essere compilato ed eseguito su una macchina, probabilmente è corretto. Tuttavia, se stai controllando questo controllo di versione in cui vivrà per sempre, ti raccomando di non farlo.

Se si fornisce un esempio del perché si desidera fare questo, io o qualcun altro può suggerire un'alternativa migliore.

MODIFICA: chiarito in base ai commenti e per chiedere un riscontro.

+3

Cosa non è portatile sui campi di bit nei sindacati rispetto ai soli campi di bit in generale? Cosa sarà in particolare difficile da prevedere? – AnT

+3

Il reclamo nel post che hai collegato riguardava la sizeof() un'unione contenente un bitfield, non il comportamento. La dimensione della stringa è sempre dipendente dall'implementazione e questo non ha nulla a che fare con il bitfield. C'era anche una lamentela per non essere in grado di prendere l'indirizzo di un membro bitfield, ma è proprio come funzionano i bitfield e non ha nulla a che fare con il sindacato. – Alan

+0

Aggiornato per essere meno vago. In generale sono iperparanoide sull'allineamento dimensione/memoria perché lavoro sul firmware dei microcontrollori. Le strutture o le variabili non allineate influiscono sulle prestazioni e possono comportare carichi e depositi non atomici. Il tuo chilometraggio può variare. –

8

Sì, possono essere. Perchè no? I campi di bit nei sindacati si comportano nello stesso modo in cui si comportano da qualsiasi altra parte. Non c'è nulla di speciale nei campi di bit nei sindacati (o nelle unioni con campi di bit).

0

Non è sicuro se si scrive su un elemento unione e si legge da uno diverso. Se i dettagli della tua implementazione assicurano che ciò non accada, allora un sindacato contenente un bitfied (e presumibilmente altri membri) ha un comportamento ben definito e sicuro.

+0

Non è stata definita l'implementazione punitiva del tipo di unione? – detly

+1

Questo non è C++: il tipo puning attraverso i sindacati è perfettamente valido in C e si comporta in modo simile a 'reinterpret_cast' di C++. La rettifica tecnica 3 lo rende chiaro. –

2

Se pensi a come funziona l'unione, hai la risposta, che è sì, certo (perché no)? Come ci aspettiamo, il sindacato è abbastanza grande da contenere il dato più grande e quindi automaticamente il più piccolo. I bitfield sono raggruppati in "contenitori" e il compilatore deve essere in grado di valutare la loro dimensione reale finale. Quanto segue mostra alcuni fatti interessanti (e ovviamente è un uso sbagliato di un sindacato, ma non per la presenza di bitfield!)

#include <stdio.h> 

union test { 
    int a:5; 
    int b:12; 
    float c; 
    double d; 
    int x; 
}; 

int main() 
{ 
    union test x; 
    printf("%d\n", sizeof(x)); 
    x.a = 31; 
    printf("%d\n", x.a); 
    printf("%d\n", x.b); 
    x.c = 1.23; 
    printf("%d\n", x.a); 
    printf("%f\n", x.c); 
    x.x = 31; 
    printf("%d\n", x.x); 
    printf("%d\n", x.a); 
    printf("%d\n", x.b); 
}