2016-04-07 16 views
6

Ho una definizione di registro fornita dal produttore del microcontrollore che può essere gestita come un campo di bit. Il registro è definito come segue: definizione del campoCast una variabile uint32 in un campo di bit - comportamento non definito?

#define SCU_WDTSCON0 (*(SCU_WDTSCON0_type *) 0xf00360f0u) 

Il bit è simile al seguente:

typedef volatile union { 
unsigned U; 
int I; 
struct { 
    unsigned ENDINIT :1; // [0:0] End-of-Initialization Control Bit 
    unsigned LCK :1; // [1:1] Lock Bit to Control Access to WDTxCON0 
    unsigned HPW0  :2; // [3:2] Hardware Password 0 
    unsigned HPW1  :4; // [7:4] Hardware Password 1 
    unsigned PW :8; // [15:8] User-Definable Password Field for Access to WDTxCON0 
    unsigned REL :16; // [31:16] Reload Value for the WDT 
    } B; 
} SCU_WDTSCON0_type; 

anziché direttamente per iscritto al registro, voglio usare una variabile di buffer Uint32 prima, ma ancora essere in grado di modificarlo secondo la definizione del campo dei bit di registro. Questa implementazione sembra funzionare, come l'indirizzo è appena sostituito con & buffer_variable:

volatile uint32 buffer_variable; 
SCU_WDTSCON0_type register_buffer = (*(SCU_WDTSCON0_type *) &buffer_variable); 

Questo potrebbe portare ad un comportamento indefinito?

+0

Questa è una buona domanda. Nella mia mente il modo per testarlo è provare lo stesso codice su due architetture, una big endian, una little endian. Mi capita di avere questi sistemi qui e se non c'è una risposta definitiva, compilerò del codice quando avrò tempo. –

+1

@DavidHoelzer Questo non ha molto a che fare con endianess. Non puoi sapere come un campo di bit memorizza i suoi bit a prescindere dall'essenza. Il comportamento dei campi di bit non è ben specificato per cominciare. [Vedi questo] (http://stackoverflow.com/questions/6043483/why-bit-endianness-is-an-issue-in-bitfields/6044223#6044223). – Lundin

+0

Onestamente, raramente li uso. Posso solo immaginare che il endianness potrebbe avere un impatto se li lanci a qualcos'altro. –

risposta

3

La variabile del buffer deve essere esattamente dello stesso tipo di uno dei membri del sindacato, in questo caso unsigned. Nel caso in cui il compilatore tratti uint32 e unsigned come tipi diversi, porterà a comportamenti non definiti (viola la regola di aliasing rigorosa). Altrimenti, se sono dello stesso tipo, il codice va bene.

(Come nota a margine, la maggior parte dei bug relativi le severe violazioni aliasing sono causati dal ottimizzatore del compilatore. In caso di variabili volatili, questo è meno di un problema, dal momento che il compilatore non è permesso di ottimizzare la loro comunque. Quindi in pratica, dubito che tu abbia mai incontrato un UB per questo scenario, anche se in teoria potrebbe essere UB.)

Problemi correlati