A. K. wrote:
> Manche betrachten "volatile" bei Arrays als überflüssig.
Meistens ist es das. Mein Argument ist eher andersrum: wenn denn
alles ordentlich funktioniert ohne volatile (und das explizite oder
implizite Wegwerfen der volatile-Kennzeichnung per Übergabe an
memcpy oder auch per Typecast bedeutet letztlich, dass es auch jetzt
bereits ohne volatile läuft), dann war die Angabe des volatile bei
der Deklaration ganz offensichtlich (zumindest für diesen Compiler)
gar nicht notwendig. Wenn sie notwendig gewesen wäre, dann hätte
sich mit dem Aufruf von memcpy() (egal ob mit oder ohne Warnung oder
mit oder ohne Unterdrückung der Warnung per Typecast) ein Fehlverhalten
eingestellt.
Es kann ja sein, dass das volatile dann noch an anderen als den hier
gezeigten Stellen notwendig ist, aber dann kann man an diesen Stellen
auch explizit den Typecast nach volatile angeben stattdessen. Bspw.
könnte man das berühmt berüchtigte Flag, das in der ISR gesetzt wird,
rein nur bei der Abfrage volatile machen. Also statt:
1 | #include <avr/io.h>
|
2 |
|
3 | extern uint8_t flag;
|
4 |
|
5 | void
|
6 | doit(void)
|
7 | {
|
8 | PORTB = 42;
|
9 | while (!flag) // funktioniert so nicht!
|
10 | /* wait */;
|
11 | PORTB = 0x2a;
|
12 | }
|
1 | #include <avr/io.h>
|
2 |
|
3 | extern uint8_t flag;
|
4 |
|
5 | void
|
6 | doit(void)
|
7 | {
|
8 | PORTB = 42;
|
9 | while (!*(volatile uint8_t *)&flag) // das klappt
|
10 | /* wait */;
|
11 | PORTB = 0x2a;
|
12 | }
|