program test;
uses
sysutils;
const
BUFLEN = 20;
var
Buf0: array[0..BUFLEN-1] of char;
Buf1: array[1..BUFLEN] of char;
s: string;
begin
// Fillchar...
// StrPLCopy...
SetString(s, Buf1, Length(Buf1));
// Error: Incompatible type for arg no. 2: Got "Array[1..20] Of Char", expected "PChar"
SetString(s, Buf0, Length(Buf0));
// compiles ok
end.
In C/C++, we use array names as pointers very often. In Delphi, we can also implement this like the example above.
Though, using the Buf1
array in FreePascal's SetString()
causes an error, while the Buf0
array works just fine. An array's base index shouldn't matter, right?
Is there any documentation that justifies this behaviour?
Tested in FPC 3.0.4 and Delphi 10.3.
If you look at the definition you link to, the 2nd argument can be one of the following types:
Buf: PAnsiChar;
Buf: PWideChar;
Buf: PChar;
Buf: PUnicodeChar;
Buf: PChar;
Buf: PWideChar;
Buf: PChar;
If you remove the duplicates / aliases, you get the following possibilities:
Buf: PAnsiChar;
Buf: PWideChar;
Buf: PUnicodeChar;
In the {$X+} state, there is a built-in type compatibility between:
PAnsiChar <-> ARRAY[0..nn] OF AnsiChar
PWideChar <-> ARRAY[0..nn] OF WideChar
PUnicodeChar <-> ARRAY[0..nn] OF UnicodeChar
As you can see above, all the Char arrays that are compatible with PChar-types all have a lower index of 0. That's just how the compiler type compatibility works. The reason for this is that it this type compatibility mainly is for easier conversion of C(++) code, and C(++) doesn't have the ability to specify a lower limit of (ordinary) arrays - they are always 0.
So the same is done in Delphi / FreePascal in order to remain (as much as possible) compatible with C(++).