Recent

Author Topic: ptrint (is considered harmfull)  (Read 1972 times)

kegge13

  • New Member
  • *
  • Posts: 45
    • the BistroMath project
ptrint (is considered harmfull)
« on: May 10, 2020, 01:42:44 pm »
According to https://www.freepascal.org/docs-html/rtl/system/ptrint.html
PtrInt was a "mistake".

Now I want to intercept the clipboard (programming for windows only) and found:

PrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrInt(@WndCallback)));

Here WNDPROC traces back to a signed integer in fpc 3.0.4 systemh.inc:
WNDPROC -> LRESULT -> LONG_PTR -> PtrInt  = Int64 or LongInt (cpu32)

However the PtrInt help advices to use PtrUint instead. So I did.

PrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrUInt(@WndCallback)));

This compiles and works as expected.
Is the implementation in fpc 3.0.4 systemh.inc correct or should this also be PtrUint?

Thanks in advance for any clarification.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: ptrint (is considered harmfull)
« Reply #1 on: May 10, 2020, 01:58:13 pm »
This may be corrected in 3.2.0 already, so check that. It is close (Weeks) to release. If it isn't file a bug. The docs are correct.
Maybe Marco can have a look at it.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

eljo

  • Sr. Member
  • ****
  • Posts: 468
Re: ptrint (is considered harmfull)
« Reply #2 on: May 10, 2020, 02:22:36 pm »
According to https://www.freepascal.org/docs-html/rtl/system/ptrint.html
PtrInt was a "mistake".
True, in the sense that it requires attention for pointer arithmetic.
Now I want to intercept the clipboard (programming for windows only) and found:

PrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrInt(@WndCallback)));

Here WNDPROC traces back to a signed integer in fpc 3.0.4 systemh.inc:
WNDPROC -> LRESULT -> LONG_PTR -> PtrInt  = Int64 or LongInt (cpu32)

However the PtrInt help advices to use PtrUint instead. So I did.

PrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrUInt(@WndCallback)));

This compiles and works as expected.
Is the implementation in fpc 3.0.4 systemh.inc correct or should this also be PtrUint?
If all you do is pass the pointer around as an integer then either will work correctly.

The moment you start using the parameter to calculate offsets and sub values in the memory pointed, is the moment you will get in trouble with ptrint, because it accepts negative values and values in the negative range are handled differently arithmetically.
So adding or extracting offsets in a ptrint type might not get you in the spot expected, this was solved with ptruint.

So PtrUint always sage PtrInt half the time safe.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: ptrint (is considered harmfull)
« Reply #3 on: May 10, 2020, 03:03:37 pm »
So adding or extracting offsets in a ptrint type might not get you in the spot expected, this was solved with ptruint.
So PtrUint always sage PtrInt half the time safe.
If the clipboard is assigned in a range high(prtint)+1 or higher, you are already in trouble. Not only with calculations...
See the docs, that explicitly mention that.

Anyway, your explanation is like hitting a nail with a plier, it works, but not intentionally. It should be corrected if the call is still ptrint. I will look it up.
« Last Edit: May 10, 2020, 03:15:39 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11452
  • FPC developer.
Re: ptrint (is considered harmfull)
« Reply #4 on: May 10, 2020, 03:08:49 pm »
The trouble is that early Delphi didn't have 32-bit unsigned, and translated a lot of unsigned 32-bit values as signed 32-bit.

Then 64-bit happened, and again the same with 64-bit unsigned.

Usually it is no problem, but may give some warnings.

In some cases, there can be real problems (where the high bit is mutilated), but usually that is somewhat dirty code.

In this case, afaik lparam's declaration of wndproc is still defined as a signed type.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5478
  • Compiler Developer
Re: ptrint (is considered harmfull)
« Reply #5 on: May 10, 2020, 04:20:46 pm »
According to https://www.freepascal.org/docs-html/rtl/system/ptrint.html
PtrInt was a "mistake".

Now I want to intercept the clipboard (programming for windows only) and found:

PrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrInt(@WndCallback)));

Here WNDPROC traces back to a signed integer in fpc 3.0.4 systemh.inc:
WNDPROC -> LRESULT -> LONG_PTR -> PtrInt  = Int64 or LongInt (cpu32)

However the PtrInt help advices to use PtrUint instead. So I did.

PrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle, GWL_WNDPROC, PtrUInt(@WndCallback)));

This compiles and works as expected.
Is the implementation in fpc 3.0.4 systemh.inc correct or should this also be PtrUint?

Thanks in advance for any clarification.

For cases like this (e.g. converting a address to a function) it doesn't really matter if you use PtrUInt or PtrInt (more correct in this example would be LONG_PTR anyway), it's only the same that matters (namely that the size is the same as the size of a pointer). Where it does matter however and PtrInt might lead to pitfalls is if pointer arithmetic is involved. That should probably be explained a bit better in the documentation as after all Delphi introduced NativeUInt and NativeInt as well (which in FPC are aliased to PtrUInt and PtrInt).

 

TinyPortal © 2005-2018