2014-10-19 19 views
8

Io sto usando un file di intestazione nel mio progetto che ha avuto il seguente define (s):C'è qualche ragione per dichiarare qualcosa "volatile const" in C ma solo "volatile" in C++?

#ifdef __cplusplus 
    extern "C" { 
#endif 

#ifdef __cplusplus 
    #define __I  volatile    /*!< Defines 'read only' permissions*/ 
#else 
    #define __I  volatile const  /*!< Defines 'read only' permissions*/ 
#endif 

Il __I è utilizzato come segue in un altro file di intestazione:

typedef struct { 
    // more members before   
     __I uint32_t CR; /*!< GPIO Commit*/ 
    // more members after 

    } GPIOA_Type; 

#define GPIOF_BASE      0x40025000UL 
#define GPIOF       ((GPIOA_Type *) GPIOF_BASE) 

La mia domanda è perché sarebbe il __I deve essere fatto const in C ma non in C++? Puoi ancora modificare il valore che CR sta indicando poiché hai l'indirizzo, ma sono solo curioso perché la definizione di __I è diversa.

Per chiunque sia interessato di cosa si tratta per o, i __I definisce sono da IAR Embedded Workbench per ARM Cortex-M4 , e struct da file di Texas Instruments LM4F120H5QR CMSIS.

+1

In C++ 'const' conferisce il collegamento interno. Non so se lo faccia in C, ma sospetto di no. Ad ogni modo, si noti che '__I' è un nome riservato all'implementazione e non deve essere utilizzato nel codice utente. –

+0

@Mat McNabb intendevo dire che dal momento che ho l'indirizzo esatto del registro CR posso fare quanto segue #define GPIO_PORTF_CR_R (* ((volatile unsigned long *) 0x40025524)), quindi fare GPIO_PORTF_CR_R = xxxxx, e che cambia il valore del registro . – SoftwareDev

+0

@SoftwareDev OK - il 'volatile const CR' significa che non è possibile usare' CR' per modificare il registro; ovviamente può essere modificato in altri modi –

risposta

7

In C++, le variabili const sono predefinite per il collegamento statico, che non sarebbe auspicabile per GPIO mappati in memoria. La correzione "giusta" per questo è la parola chiave extern, ma non può essere utilizzata qui, poiché evidentemente __I deve funzionare anche con i membri della classe. Quindi, eliminando const, il collegamento predefinito è extern, come desiderato.

+0

Se questo è il motivo, osserverei anche che chiunque abbia scritto il codice originale probabilmente dovrebbe avere "forked" '__I' per avere una versione diversa per le variabili membro che per le globali –

+0

@MattMcNabb: Hindsight è sempre 20-20. Il supporto per C++ è stato probabilmente aggiunto molto tempo dopo che la macro era stata usata nel codice C sia per i globali che per i membri. –

+0

@ BenVoigt Ha senso. Quindi, in pratica, la persona che ha scritto questo codice ha detto "non c'è modo di fare leggere CR solo in C++ anche se questo è ciò che vogliamo"? Anche se mi sto appoggiando di più verso la persona che ha scritto il codice C non leggendo correttamente la scheda tecnica perché in base al valore del registro CR può essere cambiato dal valore predefinito, infatti se non può essere modificato non c'è modo di abilitare un pull-up resistenza in uno degli interruttori nella scheda di sviluppo sto usando. – SoftwareDev