delphi - valor - ¿Es seguro tipear la conversión de TABLA<X> a una matriz de X?
multiplicacion de matrices con incognitas (3)
Hoy descubrí un error de compilación ( QC#108577 ).
El siguiente programa no se compila:
program Project1;
{$APPTYPE CONSOLE}
procedure P(M: TArray<TArray<Integer>>);
begin
SetLength(M, 1, 2);
end;
begin
end.
El compilador se SetLength
en la línea SetLength
y dice:
[dcc32 Error] E2029 '')'' expected but '','' found
Sé que podría arreglarlo así:
procedure P(M: TArray<TArray<Integer>>);
var
i: Integer;
begin
SetLength(M, 1);
for i := low(M) to high(M) do
SetLength(M[i], 2);
end;
Pero, naturalmente, estoy dispuesto a evitar tener que recurrir a esto.
La siguiente variante compila y parece funcionar:
procedure P(M: TArray<TArray<Integer>>);
type
TArrayOfArrayOfInteger = array of array of Integer;
begin
SetLength(TArrayOfArrayOfInteger(M), 1, 2);
end;
No sé lo suficiente acerca de los detalles de implementación de los arreglos dinámicos, la TArray<T>
, el recuento de referencias, etc. para estar seguro de que esto es seguro.
¿Hay alguien por ahí que sepa lo suficiente como para decir de una manera u otra si esto producirá el código correcto en el tiempo de ejecución?
El procedimiento intrínseco del compilador SetLength
construye una matriz de dimensiones sobre la marcha en la pila y llama a DynArraySetLength
para cualquier matriz dinámica, ya sea genérica o no. Si una matriz genérica no fuera estructuralmente compatible con una matriz dinámica regular, posiblemente no se llamaría la misma implementación para establecer la longitud.
De hecho, la documentation de DynArraySetLength
ofrece SetLength
como una alternativa para arreglos multidimensionales. DynArraySetLength
también podría usarse en lugar de un encasillado, pero no veo ninguna razón para preferir una u otra.
Recientemente fui mordido por el hecho de que DynamicArray<T>
y TArray<T>
en C ++ se implementan de manera diferente ( DynamicArray
es una clase independiente, mientras que TArray
es un descendiente TObject
), lo que implica que la array of T
y TArray<T>
hacen También tienen algunas diferencias de implementación en Delphi. Ciertamente producen al menos diferentes tipos de RTTI. ¿Cuál fue la causa raíz de un problema en algunos de mis códigos C ++ que comenzaron a fallar cuando el compilador Delphi comenzó a TArray
en archivos HPP para la array of ...
Delphi array of ...
tipos array of ...
lugar de DynamicArray
de DynamicArray
?
Mediante el diseño de la implementación de genéricos, funcionará el uso de un mapa manual para una array of array of Integer
.
¡Pero aquí no hay beneficio de usar genéricos!
Sólo el código:
type
TArrayOfArrayOfInteger = array of array of Integer;
procedure P(M: TArrayOfArrayOfInteger);
begin
SetLength(TArrayOfArrayOfInteger, 1, 2);
end;
Tenga en cuenta también que dicho TArray<>
o array of ..
se pasan por valor y se copian en la pila, a menos que especifique const
o var
:
procedure P(var M: TArrayOfArrayOfInteger);
begin
SetLength(TArrayOfArrayOfInteger, 1, 2);
end; // now caller instance of the parameter will be resized
var A: TArrayOfArrayOfInteger;
...
A := nil;
P(A);
assert(length(A)=1);
assert(length(A[0])=2);