0

I have the following program.

var a: PChar := PChar('abc');
ShowMessage(Format('%p - %p', [@a, a]));

When I run it, I got this error:

Project Project1.exe raised exception class EConvertError with message 'Format '%p - %p' invalid or incompatible with argument'.

The problem is that a can't be formatted as %p. But as I understand, PChar is defined as ^Char. So a PChar is essentially a pointer to Char. It's a pointer. Why can't format it as %p? The following code works without any issue:

var c: Char := 'x';
var a := @c;

Format('%p - %p', [@a, a]);   // 0019F364 - 0019F36A

Fajela Tajkiya
  • 629
  • 2
  • 10
  • 1
    Yes it's a pointer, but it's more than that. It's a pointer to null terminated array of char. Just cast it `Pointer(a)` – David Heffernan Mar 24 '22 at 07:12
  • 1
    I believe the reason it works is that "@c" is of type POINTER and not of type PChar (do you have "Typed @ operator" compiler setting enabled? If not, @ is of type POINTER). Try with "var a : PChar = @c;" instead, where you explicitly set the variable to type PChar, or try inserting a {$T+} compiler option at the top of your UNIT. – HeartWare Mar 24 '22 at 07:35

1 Answers1

1

The last parameter of Format() is an array of const (essentially, an array of TVarRec). A typed PChar pointer is stored in the TVarRec.VPChar field (TVarRec.VType=vtPChar), whereas untyped pointers are stored in the TVarRec.VPointer field (TVarRec.VType=vtPointer). The %p specifier is supported only for the VPointer field. Only the %s specifier is supported for the VPChar field.

So, you will have to type-cast PChar to Pointer if you want to use %p.

I have filed a report with Embarcadero about this:

RSP-37775: Update SysUtils.Format() to allow %p for all types of pointers

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770