Volatile in C++

Gast #2852472
Lesenswert?

Hallo Leute!

Ich programmiere schon seit einiger Zeit Microprozessoren in C. Wenn ich 
nun eine Variable hatte, auf welche ich aus dem Hauptpgrogramm und aus 
einer IRQ-Routine zugreifen wollte, habe ich die Codeoptimierung mittels 
"volatile" abgeschaltet.
1
volatile uint16_t test=0;

Nun bin ich aber dabei, dass ich meine ersten Gehschritte in C++ mache.
Hier ist es möglich, ganze Klassen als Volatile zu instanziieren. Ich 
verstehe nicht, warum nach einer "volatile"-Instanziierung der Klasse 
auch die Methoden von "volatile" sein müssen, falls sie benutzt werden. 
In C bezieht sich das "Volatile" ausschließlich auf Variablen 
(Datentypen) und nicht auf Funktionen.
1
class auto
2
{
3
public:
4
uint16_t geschwindigkeit;
5
uint16_t farbe;
6
uint16_t gewicht;
7

8
uint16_t blinker_ein(uint16_t var);
9
uint16_t blinker_aus(uint16_t var) volatile;
10
}
11

12
...
13

14
int main(void)
15
{
16
volatile auto v_a1;
17
auto a2;
18

19
v_a1.blinker_ein(10); // Compilerfeher
20
a2.blinker_ein(10; // Okay
21

22
v_a1.blinker_aus(10); // Okay
23
a2.blinker_aus(10); // Okay
24

25
...

Warum, muss wie in diesem Beispiel gezeigt, die Methode "blinker_ein" 
mit Volatile deklariert werden und was macht "Volatile" mit der Methode?

Vielen Dank im Voraus.

Schöne Grüße

Martin
Gast #2852612
Lesenswert?

Okay, danke, dummer Fehler.
1
class car
2
{
3
public:
4
uint16_t geschwindigkeit;
5
uint16_t farbe;
6
uint16_t gewicht;
7

8
uint16_t blinker_ein(uint16_t var);
9
uint16_t blinker_aus(uint16_t var) volatile;
10
}
11

12
...
13

14
int main(void)
15
{
16
volatile car v_a1;
17
car a2;
18

19
v_a1.blinker_ein(10); // Compilerfeher
20
a2.blinker_ein(10; // Okay
21

22
v_a1.blinker_aus(10); // Okay
23
a2.blinker_aus(10); // Okay
24

25
...
Gast #2852653
Lesenswert?

Martin schrieb:
> int main(void)
> {
> volatile car v_a1;
> car a2;

ich habe das gefühl das du den Sinn von volatile nicht 100% verstanden 
hast. Warum willst du hier die Variable  v_a1 volatile machen? du kannst 
sowieso nicht aus einer ISR darauf zugreifen weil sie in main lokal 
deklariert ist.

Das ganze macht nur bei globalen Variaben einen sinn. (bzw. globalen 
objekten)
#2852664
Lesenswert?

Martin schrieb:
> Ich
> verstehe nicht, warum nach einer "volatile"-Instanziierung der Klasse
> auch die Methoden von "volatile" sein müssen, falls sie benutzt werden.

Der Code der Methode ist für alle instantiierten Objekte der Gleiche. 
Wie kann nun also dieser Code anhand des ihm übergebenen this-Pointers 
sehen, ob das Objekt volatile ist, oder nicht? Er kann es schlicht 
nicht. Mit dem volatile sagst du der Methode, dass sie "ihr" Objekt 
grundsätzlich als volatile ansehen soll. Und von einem volatile-Objekt 
kannst du dann natürlich nur volatile-Methoden aufrufen, eben weil nur 
diese von einem volatile-Objekt ausgehen und damit entsprechenden Code 
enthalten.
Gast #2852709
Lesenswert?

Aber ich verseht nicht, wozu das notwendig ist, dass Methoden ihr Objekt 
als "volatile" ansehen sollen.
Geht es nicht vielmehr nur um die einzelnen Attribute (z.B. 
geschwindigkeit, farbe, gewicht), dass diese ohne Verzögerung in den 
Speicher geschrieben oder vom Speicher geholt werden sollen, damit eine 
IRQ-Routine ebenfalls darauf zugreifen kann?

Was ist so wichtig daran, dass die Metode selbst als "volatile" 
gekennzeichnet wird?

Wenn ich z.B.
1
#include<stdint.h>
2

3
class car
4
{
5
public:
6
volatile uint16_t geschwindigkeit;
7
volatile uint16_t farbe;
8
volatile uint16_t gewicht;
9

10
uint16_t blinker_ein(uint16_t var);
11
uint16_t blinker_aus(uint16_t var);
12
}
13

14
car a1;
15

16
int main(void)
17
{
18

19
a1.blinker_ein(10);
20

21
...

In diesem Beispiel instanziiere ich zwar das Objekt "a1" nicht mit 
"volatile", aber die drei Attribute in der Klasse selbst sind mit 
"volatile" gekennzeichnet. Auf diese Weise kann ich aus einer 
IRQ-Routine ohne Probleme auf diese Attribute zugreifen, ohne, dass das 
ganze Objekt als "volatile" instanziiert werden muss und die Methoden 
muss man auch nicht separat kennzeichnen.

Ich verstehe die Vorteile und Nachteile zwischen den beiden Beispielen 
nicht.

Entschuldigt, meine Unwissenheit, ich stehe in C++ noch ziemlich am 
Anfang.
Persönliche Seite #2852726
Lesenswert?

Martin schrieb:
> dass diese ohne Verzögerung in den  Speicher geschrieben
> oder vom Speicher geholt werden sollen, damit eine
> IRQ-Routine ebenfalls darauf zugreifen kann

Das hat überhaupt nix mit IRQ, Optimierung oder "verzögerungen" zu tun, 
sondern sagt einfach nur dem Compiler, dass sich die Variable außerhalb 
seines Sichtbereiches jederzeit ändern kann, oder das schreiben auf 
diese für den Compiler nicht vorhersehbare Seiteneffekte hat.

Dasd führt dann dazu, dass bestimmte Optimierungen/Änderungen nicht 
durchgeführt werden dürfen.
Gast #2852923
Lesenswert?

Ist auch sinnvoll so. Dadurch können für Objekte, die volatile sind, 
auch nur Memberfunktionen, die als volatile deklariert sind, aufgerufen 
werden. Nur in denen ist auch sichergestellt, daß die Anforderungen, die 
volatile an den vom Compiler erzeugten Code stellt, auch erfüllt sind.
Gast #2853246
Lesenswert?

Vielen Dank für eure Antworten!

Ich werde mich noch eingehender mit dem Thema beschäftigen, aber ihr 
habt mich mit euren Erklärungen bereits ein die richtige Richtung 
geführt.

Schöne Grüße

Martin

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren