パラメータータイプがcharのオープン配列である場合、charの動的な配列は許可されていますか?
-
04-10-2019 - |
質問
私は見ていました Delphi:charとtchararrayの配列「互換性のないタイプ」 そして実験を始めました。私が発見したことはかなり興味深いです。
procedure Clear(AArray: array of Integer);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := 0;
end;
var
MyArray: array of Integer;
begin
Clear(MyArray);
end.
この単純な小さな例は、オープン配列パラメーターを使用して動的配列を手順に渡す方法を示しています。予想通りにまさにコンパイルして実行されます。
procedure Clear(AArray: array of Char);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
var
MyArray: array of Char;
begin
Clear(MyArray);
end.
ここにほぼ同一のコードがあります唯一の違いはそれがの配列を使用することです Char
それよりも Integer
. 。コンパイルしません。代わりに、コンパイラが吐き出します。
E2010 Incompatible types: 'Array' and 'Dynamic array'
なぜこれがそうなのでしょうか?
しばらく検索した後、私は発見しました これ QCレポート。私はDelphi 2009を実行していますが、それでもまだ起こっています。
解決
ドキュメントでは、動的配列と互換性があるタイプcharのオープン配列パラメーターに特に言及しているため、これはバグである必要があります。から 「オープン配列パラメーター」:
function Find(A: array of Char):
整数;
[...]
ノート: ...]前の例では、動的配列を含む(ただしこれらに限定されない)char要素の配列を取得する関数を作成します。 [...
他のヒント
この種の配列を使用して、独自のタイプを定義できます。
type
TCharDynArray = array of char;
procedure Clear(AArray: TCharDynArray);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
procedure test;
var
MyArray: TCharDynArray;
begin
Clear(MyArray);
end;
このコードは正常にコンパイルされます。もちろん、有用なことは何もありません(Aarrayパラメーターは「var」として設定されていないため、すべてのアイテムに#0を割り当てる前にスタックにコピーされます)。しかし、少なくとも、それはコンパイルされます。
実際には、ダイナミックアレイ(TintegerDynarrayなど)に高レベルのタイプを簡単に定義または使用できることがわかりました。 、そしてあなたのコードをより速くします。
PCHARへのマッピングについては、すべての動的な配列に対して通常です。TintegerDynarrayをポインターにマップしてから、PintegerまたはPintegerArrayとして使用できます。
procedure AddInteger(var Values: TIntegerDynArray; Value: integer);
var n: integer;
begin
n := Length(Values);
SetLength(Values,n+1);
Values[n] := Value;
end;
procedure Loop(V: PInteger);
begin
if V<>nil then
while V^<>0 do begin
write(V^,' ');
inc(V); // go to next integer in array
end;
end;
var IntArray: TIntegerDynArray;
begin
Loop(pointer(IntArray)); // will display nothing, since pointer(IntArray)=nil for IntArray=[]
AddInteger(IntArray,2);
AddInteger(IntArray,3);
AddInteger(IntArray,0);
Loop(pointer(IntArray)); // will display '2 3 '
end.
問題は、「整数の配列」と矛盾する「チャーの配列」コードが、確かにコンパイラの内在性であることと、PCHEが文字列にタイプキャストできるという事実です。
その理由はそれだと思います array of Char
と互換性があります PChar
, 、このコードがコンパイルされているため:
procedure Clear(AArray: array of Char);
var
I: Integer;
begin
for I := Low(AArray) to High(AArray) do
AArray[I] := #0;
end;
var
MyArray: array of Char;
P: PChar;
begin
Clear(P^);
end.
それはおそらく歴史的な理由のためです。
うまくいけば バリー・ケリー また ダニー・ソープ キックインして、これについてさらにフィードバックを提供します。
- ジェロエン