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?
Ich frage mich, ob Sie volatile Methoden genauso machen können, wie Sie const Methoden machen können. –
Leere test() {} flüchtigen kompiliert auf VS2012, aber ich weiß nicht, was es bedeutet, wie ich sie noch nie flüchtig benutzt habe. –
@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