mikrocontroller.net

Forum: Compiler & IDEs dereferencing type-punned pointer - was ist das?


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze in meinem Code die folgende Funktion, die dazu gedacht ist, 
die gcc Software-Libraries zu ersetzen.

Beim Compilieren krieg ich den Fehler "warning: dereferencing 
type-punned pointer will break strict-aliasing rules". Ich konnte leider 
nichts finden, warum der Fehler auftritt und was das impliziert.

Ich würde auch lieber die Daten gleich per reference übergeben, aber 
leider ist der Prototyp nicht verhandelbar :-)
Das gezeigerte Schreiben in fpu_regs[] hat sich als am schnellsten 
herausgestellt, somit würde ich das auch ganz gerne beibehalten.

double __adddf3 (double,double);

double __adddf3 (double a, double b)
{
    alt_u32 * fpu_regs = (alt_u32 *) (DPFPU_BASE+0x80000000);
    
    register alt_u32 * temp_a = (alt_u32 *) &a;
    register alt_u32 * temp_b = (alt_u32 *) &b;

    fpu_regs[2] = temp_a[1];
    fpu_regs[1] = temp_a[0];
    fpu_regs[4] = temp_b[1];
    fpu_regs[3] = temp_b[0];
    .
    .
    .


    return (result);

Kann mir jemand sagen was hier passiert und wie ich die Meldung 
verhindern kann?

(den Flag -fno-strict-aliasing kenne ich, will ihn aber nach Möglichkeit 
vermeiden)

Danke,
Andy

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal in Blaue gegurgelt (ca. 18000 Treffer):

http://mail.opensolaris.org/pipermail/tools-gcc/20...

http://www.google.de/search?hl=de&q=%22dereferenci...

Da kannst eine Union definieren und die Typ-Konvertierungen (type 
punning) erreichen, indem die Daten durch die Union geschleust werden, 
allerdings ohne Pointer zu verwenden. Bei Pointern geht GCC davon aus, 
daß Pointer nicht den gleichen Speicher adressieren, wenn die zu 
dereferenzierenden Typen nicht "fast" identisch sind (sich zB nur durch 
Qualifier unterscheiden).

Also:
1) -fno-strict-aliasing
2) Code umschreiben (Unions wie beschrieben)
3) GCC optimieren lassen und evtl. inkorrekten aber dafür dann evtl. 
schnelleren Code bekommen

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die vielen Treffer bei Google hatte ich auch, nur hab ich aus der Liste 
wohl die richtigen Infos nicht gefunden.

Also wenn ich das richtig seh, bleibt mir wohl nichts anders übrig als 
das über ne union zu lösen. Die oben geschriebene Zeigervariante is halt 
so schön einfach, aber zugegebenermassen wohl doch etwas 'dirty'.
Die Funktion des Codes ist bei -O2 und -O3 genau wie gewünscht, aber 
Lösung 1) gefällt  mir eigentlich nicht, wer weiss was dann alles für 
berechtigte Warnings in Zukunft mit unterdrückt werden.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andy wrote:
> Die vielen Treffer bei Google hatte ich auch, nur hab ich aus der Liste
> wohl die richtigen Infos nicht gefunden.
>
> Also wenn ich das richtig seh, bleibt mir wohl nichts anders übrig als
> das über ne union zu lösen. Die oben geschriebene Zeigervariante is halt
> so schön einfach,

Nein, einfach finde ich das nicht. Schau mal an, welcher Code erzeugt 
wird, zB mit -save-temps -fverbose-asm (find ich aussagekräftiger als 
Dumps aus dem Assembler raus. Assemble wird damit geschrieben nach foo.s 
anstatt nach /tmp )

Adressen von Registern zu nehmen erfordert, daß für die Funktion ein 
Frame angelegt wird. Die Register werden gepushd, um Adresse nehmen zu 
können.

Mit einer Union kann das mit Register-Variablen geschehen (zumindest, 
wenn die Größe der Union "gerade" ist, also zB 1, 2, 4).

> aber zugegebenermassen wohl doch etwas 'dirty'.
> Die Funktion des Codes ist bei -O2 und -O3 genau wie gewünscht, aber
> Lösung 1) gefällt  mir eigentlich nicht, wer weiss was dann alles für
> berechtigte Warnings in Zukunft mit unterdrückt werden.

-fno-strict-aliasing unterdrückt keine Warnungen, sondern schaltet die 
entsprechende Optimierungen ab, d.h. solche, die unter der Annahme von 
strict-aliasing korrekt sind. Ohne die Option bleiben die Optimierungen 
eben aus, und damit auch Warungen, die damit im Zusammenhang stehen.

Ich schätze mal, diese Option führt kaum zu großartig 
besserem/schlechterem Code. Zudem kann man den Schalter gezielt auf die 
fraglichen Module anwenden.

Da es hier offenbar um Performance-Tweaks für ein Target mit FPU geht, 
bietet sich auch (Inline) Assembler an. Es müssen ja nur die Args in 
FPU-Register verteilt/abgeholt werden.

Weiß ja nicht, was Du vorhast, aber es kann durchaus lohnen sein, 
foo-gcc selbst anzupassen. Das würde den Call-Overhead sparen und das 
Register-Kopieren, zudem kann man genau sagen, welche REGs verwendet 
werden, und wie lange auf die FPU gewartet werden muss, etc.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.