volatile Variablen als Argument für die Funktion

8

Mit diesem Code:

%Vor%

Ich kann einige Warnungen nicht loswerden ..

Ich bekomme diese Warnung 1 an der Funktion One Prototyp

  

[Warnung] Typqualifikatoren werden ignoriert   Funktionsrückgabetyp

und ich bekomme diese Warnung 2, wo immer ich functionTwo mit einem COUNT Zeiger Argument anstelle eines int-Zeigers

  

[Warnung] wirft Abwurf-Qualifier   vom Zeigerzieltyp

offensichtlich Variablen / Zeiger können nicht auf volatile / un-volatile "geworfen" werden. aber alle Argumente müssen auch als flüchtig angegeben werden? Wie kann ich eine Bibliotheksfunktion verwenden, wenn sie bereits für eine nichtflüchtige Variable definiert ist?

BEARBEITEN : Verwenden von gcc -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wextra -Wstrict-prototypes -Wmissing-prototypes …

BEARBEITEN : Nach Jukka Suomela Ratschlag ist dies ein Codebeispiel für die Warnung zwei

%Vor%     
Hernán Eche 21.07.2010, 20:44
quelle

5 Antworten

8

Das Schlüsselwort volatile wurde entworfen, um auf Objekte angewendet zu werden, die Speicher und nicht Funktionen repräsentieren. Ein volatile int von einer Funktion zurückzugeben macht wenig Sinn. Der Rückgabewert einer Funktion wird nicht weg optimiert (mit der möglichen Ausnahme von Inlinefunktionen, aber das ist ein anderer Fall insgesamt ...), und kein externer Akteur wird es modifizieren. Wenn eine Funktion zurückgegeben wird, übergibt sie eine Kopie des Rückgabewerts an die aufrufende Funktion. Eine Kopie eines volatile -Objekts ist nicht selbst volatile . Wenn Sie also versuchen, ein volatile int zurückzugeben, führt dies zu einer Kopie, die in ein nichtflüchtiges int umgewandelt wird, was Ihre Compiler-Nachrichten auslöst. Ein volatile int* kann nützlich sein, aber kein volatile int .

Wenn Sie ein Objekt nach Wert an eine Funktion übergeben, wird eine Kopie des Objekts erstellt. Wenn Sie also volatile int als Funktionsparameter verwenden, ist eine Konvertierung erforderlich, die ein Qualifikationsmerkmal ignoriert. Eine volatile by-Adresse zu übergeben, ist durchaus sinnvoll, aber nicht wertmäßig.

Gemäß der C-Spezifikation ist das Verhalten von volatile vollständig implementierungsabhängig, also YMMV.

Verwenden Sie volatile auf diese Weise, um eine Art Compiler-Optimierung zu verhindern? Wenn ja, gibt es wahrscheinlich einen besseren Weg, es zu tun.

Bearbeiten: Unter Berücksichtigung der Aktualisierungen Ihrer Frage scheint es, dass Sie möglicherweise in der Lage sind, dies auf andere Weise zu erreichen. Wenn Sie versuchen, Compiler-Optimierungen zu besiegen, warum nicht den direkten Ansatz wählen und den Compiler einfach anweisen, einige Dinge nicht zu optimieren? Sie können #pragma GCC optimize oder __attribute__((optimize)) , um spezifische Optimierungsparameter für eine Funktion anzugeben . Zum Beispiel sollte __attribute__((optimize(0))) alle Optimierungen für eine bestimmte Funktion deaktivieren. Auf diese Weise können Sie Ihre Datentypen nicht flüchtig halten und die Artprobleme vermeiden, die Sie haben. Wenn das Deaktivieren aller Optimierungen etwas zu viel ist, können Sie auch einzelne Optimierungsoptionen mit diesem Attribut / Pragma aktivieren oder deaktivieren.

Bearbeiten: Ich konnte den folgenden Code ohne irgendwelche Warnungen oder Fehler kompilieren:

%Vor%

Diese hack "Technik" hat wahrscheinlich einige seltsame Nebenwirkungen, also teste sie gründlich vor der Produktion. Es ist höchstwahrscheinlich nicht anders, dass die Adresse direkt an ein (int*) übergeben wird, aber es werden keine Warnungen ausgelöst.

    
bta 21.07.2010 22:24
quelle
2

Es ist möglich, dass ich hier weit von der Basis entfernt bin, aber flüchtig ist nichts, was normalerweise mit dem Stapelspeicherbereich zusammenhängt. Daher bin ich mir nicht sicher, ob der folgende Prototyp wirklich Sinn macht.

%Vor%

Ich bin mir nicht sicher, wie eine zurückgegebene Ganzzahl flüchtig sein kann. Was wird den Wert von EAX verändern? Gleiches gilt für die ganze Zahl. Sobald der Wert auf den Stack geschoben wurde, damit er als Parameter übergeben werden kann, was wird seinen Wert ändern?

    
torak 21.07.2010 20:55
quelle
2

Ich verstehe nicht, warum Sie das Qualifikationsmerkmal volatile für einen Funktionsrückgabetyp haben möchten. Die Variable, der Sie den Rückgabewert der Funktion zuweisen, sollte stattdessen als volatile eingegeben werden.

Versuchen Sie, diese Änderungen vorzunehmen:

%Vor%

Wenn Sie functionTwo() aufrufen, wird das Argument explizit geworfen:

%Vor%

HTH, Ashish.

    
Praetorian 21.07.2010 21:52
quelle
2

Wenn ich

kompiliere %Vor%

mit

%Vor%

Ich bekomme keine Warnungen. Ich habe gcc 4.0, 4.2, 4.3 und 4.4 versucht. Ihre WarnungTwo klingt, als würden Sie Zeiger übergeben, keine Werte, und das ist eine andere Geschichte ...

BEARBEITEN:

Ihr aktuelles Beispiel sollte so geschrieben sein; wieder keine Warnungen:

%Vor%

BEARBEITEN:

Wenn Sie functionTwo nicht ändern können:

%Vor%

Beachten Sie, dass jeder Zugriff auf eine flüchtige Variable "besonders" ist. In der ersten Version mit functionTwo(COUNT *number) weiß functionTwo, wie man richtig darauf zugreift. In der zweiten Version mit countcopy weiß die Hauptfunktion, wie sie beim Zuweisen von countcopy = copy richtig darauf zugreift.

    
Jukka Suomela 21.07.2010 21:13
quelle
0

Es ist möglich, dass diejenigen, die es geschrieben haben, sicher sein wollten, dass alle Operationen atomar sind und alle int-Variablen als flüchtig deklariert sind (ist es eine MT-Anwendung mit schlechter Synchronisation?), also werden alle Ints aus dem Code als deklariert flüchtig "für Konsistenz".

Oder vielleicht, indem Sie den Funktionstyp als volatil deklarieren, erwarten sie, die Optimierungen der wiederholten Aufrufe für reine Funktionen zu stoppen? Ein Inkrement einer statischen Variable innerhalb der Funktion würde es lösen. Versuchen Sie jedoch, ihre ursprüngliche Absicht zu erraten, weil dies keinen Sinn ergibt.

    
ruslik 21.07.2010 21:03
quelle