2013-07-22 22 views
5

Sono uno sviluppatore C incorporato che ha recentemente iniziato a fare scherzi con il codice C++ su un dispositivo embedded e sono sicuri su come const correttezza si applica quando una classe accede ai dati volatili come la memoria registri o dati creati su un dispositivo esterno, ad esempio un convertitore da analogico a digitale (ADC).C++ Const-correttezza con volatili ed esterna dei dati Acess

Ad esempio, devo classi che si interfacciano con moduli hardware del dispositivo accedendo suoi registri mappati nella memoria tramite un puntatore, in questo modo:

class IOPin 
{ 
public: 
    /* Constructor, destructor, other methods...*/ 

    // should this be a const method? 
    bool ReadIOState() {return portregs_->state;} 

private: 
    /* Other private stuff...*/ 

    // Constructor points this to the right set of memory-mapped registers 
    volatile struct portregs_t 
    { 
     uint32_t control; 
     uint32_t state; 
     uint32_t someotherreg; 
    } *portregs_; 
}; 

I nomi di registro sono ovviamente costituiti per motivi di esempio. Sto usando un dispositivo Microchip PIC32 per chiunque sia curioso.

Dalla mia possibilmente errata comprensione, contrassegnare un metodo const significa che lo stato osservabile dell'oggetto non deve cambiare per quanto riguarda il chiamante. Così dovrebbe il metodo ReadIOState()non essere const perché accede ai dati volatile che potrebbe cambiare in qualsiasi momento e in tal modo il chiamante potrebbe osservare il cambiamento? O dovrebbe essere const perché il metodo non modifica esplicitamente qualcosa?

Attualmente, sto appoggiato verso non facendo che il metodo const per il motivo indicato nella domanda. Questo è particolarmente vero dopo aver inciampato su this GotW article, che afferma che il significato di const sta cambiando per significare "in grado di leggere contemporaneamente". La mia applicazione incorporata è single-threaded, ma suppongo che potrebbe essere una buona cartina di tornasole per const in generale.

Inoltre, come fa il compilatore trattare const metodi? Cioè, cosa succede quando voglio interrogare lo stato del IO come questo:

// wait for IO pin to go high 
while(!myIOpin.ReadIOState()) 
{} 

Se ReadIOState() è const, allora il compilatore riutilizzare il valore restituito dopo una chiamata o è abbastanza intelligente per capire che esso sta accedendo ai dati volatile e non farlo?

+0

Mi chiedo se è possibile creare metodi volatili nello stesso modo in cui è possibile creare metodi const. –

+1

void test() volatile {} compila su VS2012 ma non so cosa significhi visto che non ho mai usato volatile prima. –

+1

@NeilKirk Sì, puoi farlo. Significa che la funzione può essere invocata su un'istanza 'volatile'. Proprio come le funzioni 'const' possono essere invocate su istanze' const'. Puoi anche avere tutti e 4 i sovraccarichi di una funzione membro se ne hai voglia. – Angew

risposta

2

Si sono solo avendo puntatore alla struttura all'interno della classe e non si modifica il puntatore, in modo che il metodo può essere const. Il compilatore non deve riutilizzare il valore della precedente chiamata, è abbastanza intelligente.

+0

Grazie per la risposta! Questo è vero e continuo a dover ricordare a me stesso che è il puntatore stesso che viene reso const. Tuttavia, penso che la mia domanda sia un po 'più sul lato filosofico. Cioè, l'uso di const per un metodo implica qualcosa sul valore di ritorno del metodo? Se il valore restituito può cambiare tra due chiamate successive a un metodo, anche se la classe non è stata quella che le ha modificate, ha senso dire che è const? –

+0

Const è una parola chiave che viene utilizzata solo in fase di compilazione, in fase di esecuzione non vengono eseguiti controlli speciali relativi a const (solo nel caso in cui uno ha fortuna e il valore const è memorizzato nella pagina di memoria a sola lettura dal sistema operativo), questa parola chiave utilizzata avere più aiuto (errori di compilazione) dal compilatore al momento della compilazione. L'uso di const per metodo non implica nulla sul valore di ritorno del metodo. Questo è il lato meno intuitivo del C++. – lextiz

+0

Gotcha, grazie! –