为什么 Delphi 和 FreePascal 编译器以不同方式处理基于 0 和基于 x 的静态数组?
Why do the Delphi and FreePascal compilers handle 0-based and x-based static arrays differently?
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.
在C/C++中,我们经常使用数组名作为指针。在Delphi中,我们也可以像上面的例子那样实现。
不过,在 FreePascal 的 SetString()
中使用 Buf1
数组会导致错误,而 Buf0
数组工作正常。数组的基本索引应该无关紧要,对吧?
是否有任何文件可以证明这种行为?
在 FPC 3.0.4 和 Delphi10.3 中测试。
如果您查看 link 的定义,第二个参数可以是以下类型之一:
Buf: PAnsiChar;
Buf: PWideChar;
Buf: PChar;
Buf: PUnicodeChar;
Buf: PChar;
Buf: PWideChar;
Buf: PChar;
如果删除重复项/别名,您将获得以下可能性:
Buf: PAnsiChar;
Buf: PWideChar;
Buf: PUnicodeChar;
在 {$X+} 状态下,built-in 类型兼容:
PAnsiChar <-> ARRAY[0..nn] OF AnsiChar
PWideChar <-> ARRAY[0..nn] OF WideChar
PUnicodeChar <-> ARRAY[0..nn] OF UnicodeChar
正如您在上面看到的,所有与 PChar-types 兼容的 Char 数组都有一个较低的索引 0。这就是编译器类型兼容性的工作原理。这样做的原因是这种类型兼容性主要是为了更容易转换 C(++) 代码,而 C(++) 没有能力指定(普通)数组的下限 - 它们始终为 0 .
所以在 Delphi / FreePascal 中也做了同样的事情,以保持(尽可能)与 C(++) 兼容。
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.
在C/C++中,我们经常使用数组名作为指针。在Delphi中,我们也可以像上面的例子那样实现。
不过,在 FreePascal 的 SetString()
中使用 Buf1
数组会导致错误,而 Buf0
数组工作正常。数组的基本索引应该无关紧要,对吧?
是否有任何文件可以证明这种行为?
在 FPC 3.0.4 和 Delphi10.3 中测试。
如果您查看 link 的定义,第二个参数可以是以下类型之一:
Buf: PAnsiChar;
Buf: PWideChar;
Buf: PChar;
Buf: PUnicodeChar;
Buf: PChar;
Buf: PWideChar;
Buf: PChar;
如果删除重复项/别名,您将获得以下可能性:
Buf: PAnsiChar;
Buf: PWideChar;
Buf: PUnicodeChar;
在 {$X+} 状态下,built-in 类型兼容:
PAnsiChar <-> ARRAY[0..nn] OF AnsiChar
PWideChar <-> ARRAY[0..nn] OF WideChar
PUnicodeChar <-> ARRAY[0..nn] OF UnicodeChar
正如您在上面看到的,所有与 PChar-types 兼容的 Char 数组都有一个较低的索引 0。这就是编译器类型兼容性的工作原理。这样做的原因是这种类型兼容性主要是为了更容易转换 C(++) 代码,而 C(++) 没有能力指定(普通)数组的下限 - 它们始终为 0 .
所以在 Delphi / FreePascal 中也做了同样的事情,以保持(尽可能)与 C(++) 兼容。