Forum: Compiler & IDEs Volatile in C++


von Martin (Gast)


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

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

auto ist ein Schlüsselwort. Nenn die Klasse anders (aber nicht if, else, 
for, typedef, volatile, unsigned, main oder so, das sind alles 
Schlüsselworte in C/C++).

von Martin (Gast)


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
...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Es fehlt ein

#include <stdint.t>

uint16_t etc. werden durch stdint.h zur Verfügung gestellt.

von Peter II (Gast)


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)

von Stefan E. (sternst)


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.

von Martin (Gast)


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.

von Läubi .. (laeubi) Benutzerseite


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.

von daniel root (Gast)


Lesenswert?

das ist in Analogie zum const qualifier durchgezogen

class A {
   void foo();
   void bar()const;
};

A a;
a.foo() => ok
a.bar() => ok


const A a;
a.foo(); => not ok
a.bar(); => ok

von Rrolf Magnus (Gast)


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.

von Martin (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.