2013-07-22 15 views
5

Ich bin ein Embedded-C-Entwickler, der vor kurzem mit C++ - Code auf einem eingebetteten Gerät zu verwirren begonnen hat und unsicher bin, wie Konstanten gelten, wenn eine Klasse flüchtige Daten wie Speicher zugreift B. Register oder Daten auf einem externen Gerät, z. B. einem Analog-Digital-Wandler (ADC).C++ Const-Korrektheit mit flüchtigen und externen Datenzugriff

Zum Beispiel, ich habe Klassen, die eine Schnittstelle zu dem Hardware-Modulen des Geräts durch seine Memory-Mapped Zugriff auf Register über einen Zeiger, etwa so:

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_; 
}; 

Die Registernamen natürlich sind aus Gründen, bestehend aus Beispiel. Ich benutze ein Microchip PIC32 Gerät für alle, die neugierig sind.

Von meinem möglicherweise inkorrektem Verständnis bedeutet das Markieren einer Methode const, dass sich der beobachtbare Zustand des Objekts nicht so weit ändern sollte, wie der Anrufer betroffen ist. Also sollte die ReadIOState() Methode nichtconst sein, weil es auf volatile Daten zugreift, die sich jederzeit ändern könnten und somit der Anrufer die Änderung beobachten würde? Oder sollte es const sein, weil die Methode nichts explizit ändert?

Momentan lehne ich mich an, diese Methode const aus dem in der Frage angegebenen Grund nicht zu machen. Dies gilt insbesondere nach dem Stolpern über this GotW article, das besagt, dass sich die Bedeutung von const ändert, um zu bedeuten "fähig, gleichzeitig zu lesen". Meine embedded Anwendung ist Single-Thread, aber ich nehme an, dass ein guter Lackmustest für const ness im Allgemeinen sein könnte.

Auch, wie behandelt der Compiler const Methoden? Das heißt, was passiert, wenn ich den Zustand des IO wie folgt abfragen wollen:

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

Wenn ReadIOState()const ist, dann kann der Compiler den Wert wiederverwenden, nachdem ein Aufruf zurückgegeben oder ist es klug genug, dass es zu sehen Zugriff auf volatile Daten und nicht das tun?

+0

Ich frage mich, ob Sie volatile Methoden genauso machen können, wie Sie const Methoden machen können. –

+1

Leere test() {} flüchtigen kompiliert auf VS2012, aber ich weiß nicht, was es bedeutet, wie ich sie noch nie flüchtig benutzt habe. –

+1

@NeilKirk Ja, Sie können es tun. Dies bedeutet, dass die Funktion in einer "flüchtigen" Instanz aufgerufen werden kann. Genauso wie 'const' Funktionen in' const' Instanzen aufgerufen werden können. Sie können sogar alle 4 Überladungen einer Mitgliedsfunktion haben, wenn Ihnen danach ist. – Angew

Antwort

2

Sie haben nur Zeiger auf die Struktur innerhalb der Klasse und Sie ändern den Zeiger nicht, so kann die Methode const sein. Der Compiler sollte den Wert des vorherigen Aufrufs nicht wiederverwenden, er ist intelligent genug.

+0

Danke für die Antwort! Das ist wahr und ich muss mich immer wieder daran erinnern, dass es der Zeiger selbst ist, der const gemacht wird. Ich denke jedoch, meine Frage ist ein bisschen mehr auf der philosophischen Seite. Das heißt, bedeutet die Verwendung von const für eine Methode irgendetwas über den Rückgabewert der Methode? Wenn der Rückgabewert zwischen zwei aufeinanderfolgenden Aufrufen einer Methode wechseln kann, obwohl die Klasse nicht diejenige war, die sie geändert hat, macht es Sinn zu sagen, dass es const ist? –

+0

Const ist ein Schlüsselwort, das nur zur Kompilierzeit verwendet wird. Zur Laufzeit werden keine speziellen const-Prüfungen ausgeführt (nur wenn man Glück hat und const-Wert auf der Nur-Lese-Speicherseite nach Betriebssystem gespeichert ist), dieses Schlüsselwort wird nur verwendet mehr Hilfe (Kompilierungsfehler) vom Compiler zur Kompilierungszeit haben. Die Verwendung von const für Methode impliziert nichts über den Rückgabewert der Methode. Dies ist weniger intuitive Seite von C++. – lextiz

+0

Gotcha, danke! –