Forum: Compiler & IDEs -Wignored-qualifiers


von Bronco (Gast)


Lesenswert?

Hallo zusammen,

ich programmiere einen STM32 in C++ mit Atollic TrueSTUDIO.

Jetzt hab ich folgendes Konstrukt erstellt:
1
class meineklasse_t
2
{
3
public:
4
  volatile uint16_t GetWert(void) { return(WertAusISR_u16); }
5
private:
6
  volatile uint16_t WertAusISR_u16; // Wird im Interrupt beschrieben
7
};

Nun bekomme ich für die Funktion "GetWert()" die Warnung
1
warning: type qualifiers ignored on function return type [-Wignored-qualifiers]

Unter
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
finde ich dazu die Erklärung
1
Warn if the return type of a function has a type qualifier such as const. For ISO C such a type qualifier has no effect, since the value returned by a function is not an lvalue. For C++, the warning is only emitted for scalar types or void. ISO C prohibits qualified void return types on function definitions, so such return types always receive a warning even without this option.

Meine Fragen:
1. Wenn ich die Warnung richtig verstehe, heisst das soviel wie "eine 
Funktion gibt ihr Ergebnis immer in einem Register (oder auf dem Stack) 
zurück, daher kann das Ergebnis keinen Qualifier haben, denn der wäre 
mit einer Speicheradresse verknüpft". Stimmt das so?
2. Ist es gewährleistet, daß die Funktion immer aufgerufen, egal wie 
stark der Compiler zu optimieren versucht?

Danke!

von Jope (Gast)


Lesenswert?

volatile mach nur Sinn für sog. lvalues (C-Standard-Terminologie), 
also Variablen ("L = R"). Das was Deine Funktionen zurückgeben sind aber 
rvalues. Du kannst den Funktionen selbst ja nichts zuweisen:
1
GetWert() = 10;

sondern Du weist Variablen damit einen Wert zu
1
bla = GetWert();

Und deshalb wird das volatile ignoriert.
Es wäre ja auch unsinnig, eine zahl auf volatile zu casten
(mal abgesehen davon, dass das gar nicht kompiliert):
1
volatile int val = volatile(10);

von Jope (Gast)


Lesenswert?

Sorry, zu schnell, natürlich gehört eine Klammer um volatile, dann 
kompiliert es auch. Ändert aber nichts. Ist trotzdem nutzlos.

von Dr. Sommer (Gast)


Lesenswert?

Jope schrieb:
> Sorry, zu schnell, natürlich gehört eine Klammer um volatile, dann
> kompiliert es auch. Ändert aber nichts. Ist trotzdem nutzlos.
Ne, das wär sogar richtig:
1
int irgendwas = int (wasanderes);
ist ein Cast nach int. Sieht man nur nicht so oft. in C++ sollte man 
onehin keine solchen C-Casts mehr verwenden, sondern nur named casts, 
also reinterpret_cast, static_cast, dynamic_cast, const_cast ...
Dafür beim GCC mit -Werror=old-style-cast compilieren ;-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bronco schrieb:

> 2. Ist es gewährleistet, daß die Funktion immer aufgerufen, egal wie
> stark der Compiler zu optimieren versucht?

Nein.  Das kannst du erreichen mit
1
__attribute__((__noinline__,__noclone__))
und zudem darf der Body der Funktion nicht leer sein. Anstatt eines 
leeren Bodys geht
1
__asm__ ("");
was keinen Code erzeugt.

von Dr. Sommer (Gast)


Lesenswert?

> 2. Ist es gewährleistet, daß die Funktion immer aufgerufen, egal wie
> stark der Compiler zu optimieren versucht?
Wozu sollte man das wollen? Deine einfache Getter-Funktion darf doch 
problemlos wegoptimiert werden, was in schnellerem & kleinerem Code 
resultiert. Der Zugriff auf die volatile-Variable wird dabei natürlich 
nicht wegoptimiert.

von Jope (Gast)


Lesenswert?

>> Sorry, zu schnell, natürlich gehört eine Klammer um volatile, dann
>> kompiliert es auch. Ändert aber nichts. Ist trotzdem nutzlos.

>Ne, das wär sogar richtig:
>int irgendwas = int (wasanderes);
>ist ein Cast nach int. Sieht man nur nicht so oft

Ich war etwas verwirrt. Ich hatte die Zeile nur schnell mit meinem 
C-Compiler ausprobiert, aber in C ist nur die Klammer-Variante erlaubt, 
in C++ beides.

von Bronco (Gast)


Lesenswert?

Dr. Sommer schrieb:
>> 2. Ist es gewährleistet, daß die Funktion immer aufgerufen, egal wie
>> stark der Compiler zu optimieren versucht?
> Wozu sollte man das wollen? Deine einfache Getter-Funktion darf doch
> problemlos wegoptimiert werden, was in schnellerem & kleinerem Code
> resultiert. Der Zugriff auf die volatile-Variable wird dabei natürlich
> nicht wegoptimiert.

Okay, meine Frage ist eigentlich:
Ist gewährleistet, daß der Compiler nach aller Optimiererei noch weiß, 
daß es sich um eine volatile Variable handelt?
Aber wahrscheinlich schon, sonst hätten wir ein Problem...

von Dr. Sommer (Gast)


Lesenswert?

Bronco schrieb:
> Okay, meine Frage ist eigentlich:
> Ist gewährleistet, daß der Compiler nach aller Optimiererei noch weiß,
> daß es sich um eine volatile Variable handelt?
Ja, definitiv. Denn Optimierungen dürfen nicht das Verhalten ändern, und 
"volatile" schreibt nunmal ein bestimmtes Verhalten vor, das darf nicht 
einfach verschwinden. Das Verhalten, dass der Prozessor tatsächlich in 
eine Funktion springt ist aber nicht vorgeschrieben und im Allgemeinen 
auch unnötig...

von Bronco (Gast)


Lesenswert?

Okay, danke.

Dann darf ich wohl annehmen, daß die Information, die hier
http://openbook.galileocomputing.de/c_von_a_bis_z/009_c_funktionen_012.htm#t2t33
(unter Absatz "9.12.3 volatile") angegeben ist, nicht so ganz korrekt 
ist...

von Peter II (Gast)


Lesenswert?

Bronco schrieb:
> Dann darf ich wohl annehmen, daß die Information, die hier
> http://openbook.galileocomputing.de/c_von_a_bis_z/009_c_funktionen_012.htm#t2t33
> (unter Absatz "9.12.3 volatile") angegeben ist, nicht so ganz korrekt
> ist...

nein.

du hast keine Variable!

> volatile uint16_t GetWert(void)

die Methode liefert einen wert zurück und das ist nun mal keine 
Variable. Den wert kann man einer Variabel zuweisen.

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.