?? Hint: Conversion between ordinals and pointers is not portable

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von MmVisual »

Hallo,

Ich wollte das Beispiel aus der Lazarus Hilfe benutzen:
https://wiki.lazarus.freepascal.org/Asynchronous_Calls

Supereinfach und gut beschrieben, jedoch wenn ich das so anwende erscheint ein "Hint" in Lazarus. Ich verstehe nicht warum der Compiler dies als Hint anmeckert. Man erzeugt einen Pointer auf einen Record, das wird als PtrInt übergeben und ein Pointer ist doch in jedem System doch entsprechend zum PtrInt kompatibel, ich kann jetzt nicht nachvollziehen warum das an der Stelle ein "Portable" Problem darstellen könnte.

fmain.pas(611,21) Hint: Conversion between ordinals and pointers is not portable
fmain.pas(618,13) Hint: Conversion between ordinals and pointers is not portable
Bild1.png
Bild1.png (16.79 KiB) 1563 mal betrachtet
Dankeschän für die Aufklärung.

Ich weiß, ich könnte die Meldung mit {%H-} ausblenden...

VG Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: ?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von theo »

Ist ja nur ein Hinweis, keine Warnung und kein Fehler.
https://forum.lazarus.freepascal.org/in ... #msg110826

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: ?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von Winni »

Hi!

Ordinals sind 32 Bit.
Pointer sind so groß wie die CPU.
Unter 32 bit geht alles gut.
Unter 64 Bit könnte es Probleme geben.

Zweites Thema: ptrInt

Es sollte nicht benutzt werden, siehe https://www.freepascal.org/docs-html/rt ... trint.html

"The introduction of the ptrint type was a mistake. Please use ptruint instead. "

Winni

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: ?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von MmVisual »

Ich sehe in meinem Code kein "Ordinals" Typ, nur Pointer und PtrInt.
Die Zeile:
.... := PTLogMsgData(Data)^;
ist doch ein Pointer, bzw. es wird die Adresse dem Objekt zugewiesen.
TLogMsgData ist ein record.

Von daher verstehe ich nicht was hier 32 Bit sein soll, bzw. woher das Mischen 32/64 Bit nun kommt.
Ich gehe davon aus, dass alle Variablen die unter 64 Bit irgendwo im Speicher liegen auch eine 64 Bit Adresse haben.

Hier der Datentyp:

Code: Alles auswählen

  TLogMsgData = record
    strLogTxt: string;
    dtLog: TDateTime;
  end;
  PTLogMsgData = ^TLogMsgData;
Auch mit PtrUint kommt imme noch die gleiche Warnung:

Code: Alles auswählen

eceivedLogMsg := PTLogMsgData(PtrUint(Data))^;
EleLa - Elektronik Lagerverwaltung - www.elela.de

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: ?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von Warf »

Der grund dafür ist relativ einfach, denn, obwohl jeder Pointer ein Valider Integer ist, gilt das nicht anders rum. In ARM Architekturen sind Pointer aligned, d.h. die Auflösung von pointern ist kleiner (d.h. pointer $XX00 und pointer $XX01 zeigen auf die gleiche memory region). Wie mit aligned pointern umgegangen wird kann unterschiedlich sein, und ich weis nicht wie der FPC das macht. Der compiler kann beim cast die pointer normalisieren (also aus pointer $XX01 wird $XX00), oder bei der verwendung von unaligned wird eine Exception geworfen, oder die unaligned pointer werden einfach gefressen und die CPU normalisiert diese.

Daher ist eigentlich das einzige was garantiert portable ist die Conversion von Pointer -> Int -> Pointer unter der Annahme das der Int nicht verändert wird. Wenn du mit dem Int irgendwas machst dann kann es sein das am ende kein Valider pointer mehr rauskommt. Genauso kann es sein das wenn du Int -> Pointer -> Int convertierst, selbst wenn du mit dem Pointer nichts machst, der Ergebnis Integer einen anderen wert hat als der Anfangs Integer.

Da das ganze kein richtiger Fehler ist, und in vielen Fällen komplett korrekt ist, ist es nur eine Hint und keine Warning oder Error. Es soll nur darauf hinweisen das du wissens solltest was du tust, und nicht auf die Idee kommst irgendwelche Mathematik mit dem Int zu machen, wenn du es portabel halten willst.

In C ist es z.B. nicht mal garantiert das der selbe Integer vom gleichen Pointer rauskommt, also integer vergleiche (IntPtr(p) = IntPtr(p)) sind nicht zwangsläufig true. Hier ist nur definiert das Pointer intPtr(p)) = p und das IntPtr(NULL) = 0. Sonst ist alles andere Undefiniert
Zuletzt geändert von Warf am So 13. Feb 2022, 15:15, insgesamt 1-mal geändert.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von wp_xyz »

MmVisual hat geschrieben:
So 13. Feb 2022, 14:09
Ich sehe in meinem Code kein "Ordinals" Typ, nur Pointer und PtrInt.
Data ist ein PtrInt, also ein Integer-Typ, und damit ein Ordinal-Typ (man weiß zu jedem Wert den Vorgänger und Nachfolger, und es gibt einen größten und einen kleinsten Wert - https://www.freepascal.org/docs-html/ref/refsu4.html).
MmVisual hat geschrieben:
So 13. Feb 2022, 14:09
Die Zeile:
.... := PTLogMsgData(Data)^;
ist doch ein Pointer, bzw. es wird die Adresse dem Objekt zugewiesen.
TLogMsgData ist ein record.
Ja, aber Data ist eben ein Integer-Typ. Und Pointer und Integer passen von der Größe her manchmal nicht zusammen, so dass der Typecast zwischen beiden mit Vorsicht zu genießen ist - genau das sagt der Hinweis. Obwohl PtrInt genau dafür geschaffen wurde - manchmal ist FPC schon extrem kleinlich...

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: ?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von MmVisual »

@Warf
OK, danke für die ausführliche Erklärung!

Ich wusste bisher nicht dass Pointer unter anderen Systemen Aligned sein können, zumindest nicht für die Systeme die man mit dem FPC erstellt.
Von daher macht dieser Hint durchaus Sinn.

Die ARM Prozessoren ab Cortex-M3 können mit Unalligned Pointern umgehen. Nur die Cortex-M0 nicht, diese sind an dieser Funktion etwas "beschnitten" worden damit diese kleiner werden und weniger Strom verbrauchen.
Zuletzt geändert von MmVisual am So 13. Feb 2022, 15:09, insgesamt 2-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: ?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von MmVisual »

@wp_xyz

PtrInt und Pointer haben immer die gleiche Bitlänge, so steht es zumindest in der Doku:

PtrInt
Signed integer type with same size as Pointer.
EleLa - Elektronik Lagerverwaltung - www.elela.de

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: ?? Hint: Conversion between ordinals and pointers is not portable

Beitrag von PascalDragon »

wp_xyz hat geschrieben:
So 13. Feb 2022, 14:53
MmVisual hat geschrieben:
So 13. Feb 2022, 14:09
Die Zeile:
.... := PTLogMsgData(Data)^;
ist doch ein Pointer, bzw. es wird die Adresse dem Objekt zugewiesen.
TLogMsgData ist ein record.
Ja, aber Data ist eben ein Integer-Typ. Und Pointer und Integer passen von der Größe her manchmal nicht zusammen, so dass der Typecast zwischen beiden mit Vorsicht zu genießen ist - genau das sagt der Hinweis. Obwohl PtrInt genau dafür geschaffen wurde - manchmal ist FPC schon extrem kleinlich...
Das hat nichts mit kleinlich zu tun, sondern einfach damit, dass Ptr(U)Int einfach nur ein normaler Typalias in der System-Unit ist und nicht irgendein spezieller, interner Datentyp, wie zum Beispiel LongInt, Pointer und Int64 es sind. In letzterem Fall hätte der Hinweis dafür deaktiviert werden können, in ersterem geht das eben einfach nicht.
FPC Compiler Entwickler

Antworten