Ist nicht schlimm, nur sind die memcpy-Parameter ohne "volatile"
deklariert, daher das Gemecker. Kannst du vermeiden mit:
memcpy((void *)pwm_setting, (void *)pwm_setting_tmp, 8);
Wenn es mit Wegwerfen des volatile funktioniert (per Typecast), dann
war das volatile wohl auch von vornherein überflüssig, und man kann
es auch gleich ganz weglassen.
Man kann ja auch den umgekehrten Weg gehen: das volatile nur dann
per Typecast anwenden, wenn es wirklich gebraucht wird.
Manche betrachten "volatile" bei Arrays als überflüssig. Sicher bin ich
mir da nicht, allerdings sorgt mindestens die stete Gefahr von Aliasing
üblicherweise dafür dass da nichts anbrennt.
Es funktioniert in diesem Zusammenhang mit oder ohne Wegwerfen von
"volatile", nur gibt's ohne dies eine letztlich ablenkende Warnung.
Genau genommen sind explizite und ganz besonders implizite Umwandlungen
von und nach "void *" nicht viel besser als Casts die "volatile"
entfernen. Denn sie können die Erkennung von Aliasing aushebeln, weshalb
Compiler und Programmierer entsprechend wachsam sein müssen. Und weil
"char *" früher die Rolle von "void *" einnahm müssen Compiler auch
damit (per Definition) anders umgehen als mit anderen Typen. Walter
Bright (Autor vom Zortech/Symantec/DigitalMars Compiler) hatte anno
Zortech C/C++ eine eigene Ansicht zum Umgang mit "void *", und ich bin
geneigt ihm dabei Recht zu geben.
So frage ich mich auch, ob es nicht bessere Konzepte für das hinter
"volatile" stehende Problem geben kann, als ebendieses Attribut mit
seinen hässlichen Nebeneffekten (wie beispielsweise ineffiziente oder
umständlich zu programmierende Interrupt-Routinen). Aber das Kind ist
nun einmal im Brunnen und eine sauber durchdachte Sprache wird C auch in
diesem Jahrhundert nicht mehr werden.
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:
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.