?? Hint: Conversion between ordinals and pointers is not portable
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
?? Hint: Conversion between ordinals and pointers is not portable
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
Dankeschän für die Aufklärung.
Ich weiß, ich könnte die Meldung mit {%H-} ausblenden...
VG Markus
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
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
Re: ?? Hint: Conversion between ordinals and pointers is not portable
Ist ja nur ein Hinweis, keine Warnung und kein Fehler.
https://forum.lazarus.freepascal.org/in ... #msg110826
https://forum.lazarus.freepascal.org/in ... #msg110826
- 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
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
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
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: ?? Hint: Conversion between ordinals and pointers is not portable
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:
Auch mit PtrUint kommt imme noch die gleiche Warnung:
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;
Code: Alles auswählen
eceivedLogMsg := PTLogMsgData(PtrUint(Data))^;
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Beiträge: 2122
- 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
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
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.
Re: ?? Hint: Conversion between ordinals and pointers is not portable
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 Ich sehe in meinem Code kein "Ordinals" Typ, nur Pointer und PtrInt.
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 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.
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: ?? Hint: Conversion between ordinals and pointers is not portable
@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.
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
-
- Beiträge: 1581
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: ?? Hint: Conversion between ordinals and pointers is not portable
@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.
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
-
- Beiträge: 955
- 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
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.wp_xyz hat geschrieben: So 13. Feb 2022, 14:53Ja, 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 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.
FPC Compiler Entwickler