Reminder to self: Delphi 11.3 (Alexandria update 3), mid-product added a compiler changing kind of deprecating using types of this form (including ones defined in the System
, System.Types
and other RTL/VCL units):
Overview of “deprecated” * and alternative array types “deprecated” alternative: write it all out TBooleanDynArray
TArray<Boolean>
TByteDynArray
TArray<Byte>
TCardinalDynArray
TArray<Cardinal>
TStringDynArray
TArray<string>
- technically not deprecated, as
deprecated
is a hinting directive and despite these having existed for almost 25 years now**, hinting directives likeplatform
,deprecated
, orlibrary
cannot be used onarray
types:a bug has been filed for this in 2017 but still has not been addressed, see my earlier blog post Delphi Declarations and Statements: Hinting Directives.
The reminder was [Wayback/Archive] “Incompatible parameter lists” when using Types.T*DynArray? – VCL – Delphi-PRAXiS [en] (by Zoë Peterson from Scooter Software: the makers of Beyond Compare).
I have some visual components that have event handlers that are declared like so:
TSsInitEvent = procedure(Sender: TObject; var AStrs: TStringDynArray) of object;In the units that are using them, they’re declared like:
procedure CommandControlInit(Sender: TObject; var AStrs: TStringDynArray);Ctrl+Clicking shows that TStringDynArray is a direct reference to System.Types.TStringDynArray in both cases. In the older releases, TStringDynArray was “array of string”, but it’s apparently now been changed to “TStringDynArray = TArray<string>”.
That worked just fine in older Delphi releases, but in 11.3 whenever I save the form I get the error “The CommandControlInit method referenced by CommandControl.OnInit has an incompatible parameter list. Remove the reference?”
If I try to create a new event for the relevant property, it’s created like so:
procedure CommandControlInit(Sender: TObject; var AStrs: TArray<System.string>);Aside from just being a more obnoxious declaration, that doesn’t work for projects that also need to compile in older Delphi releases.
Has anyone else run into this? Any good workarounds? Any open bug reports about it I can vote for?
…
Sure, here’s a trivial example. Compile/install the
SsExample.bpl
, which adds a new minimalTSsControl
.SsProj.dproj
already has a form with the relevant control. If you make any change at all to it, you’ll get the error. If you delete the existingCtrlInit
and add a new one, it’ll switch to the generic declaration.This isn’t restricted to something as simple as
TArray<string>
though. If the argument is a much more complicated generics declaration (e,g.TDictionary<string, TDictionary<Integer, Integer>>
), that gets exploded out too. Why would that be preferable to using a named alias?[WaybackSave] DynArrayFailure.zip
I suspect you only could change the event declaration to generics or define your own alias. Type aliases have pretty much quirks (for ex., even if T1 and T2 are declared identically, they’re not compatible).
For some history (this is one of the few old documentation areas that Embarcadero did not manage to demolish), see the Delphi 2007 Help Update 4 documentation page [Wayback/Archive] Declarations and Statements.
** Delphi 6 introduced the hinting directives because of Kylix (the very first Delphi for Linux) required to know which RTL/VCL features were platform specific. A great overview on Delphi feature introduction is at [Wayback/Archive] List of Delphi language features and version in which they were introduced/deprecated – Stack Overflow: yup, outside Embarcadero is the really nitty gritty Delphi documentation (:
Hinting Directives
The ‘hint’ directives platform, deprecated, and library may be appended to any declaration. These directives will produce warnings at compile time. Hint directives can be applied to type declarations, variable declarations, class, interface and structure declarations, field declarations within classes or records, procedure, function and method declarations, and unit declarations.When a hint directive appears in a unit declaration, it means that the hint applies to everything in the unit. For example, the Windows 3.1 style OleAuto.pas unit on Windows is completely deprecated. Any reference to that unit or any symbol in that unit will produce a deprecation message.
Delphi Alexandria documentation links of various array types:
TArray<T>
based dynamic types versusarray of T
based dynamic types: not all have documentationGeneric (dynamic) array type Classic dynamic array type [Wayback/Archive] System.TBooleanDynArray
– RAD Studio API DocumentationMissing documentation for TClassicBooleanDynArray: array of Boolean;
[Wayback/Archive] System.TByteDynArray
– RAD Studio API Documentation[WaybackSave/Archive] System.Types.TClassicByteDynArray
– RAD Studio API Documentation[WaybackSave/Archive] System.TCardinalDynArray
– RAD Studio API DocumentationMissing documentation for TClassicCardinalDynArray: array of Cardinal;
[Wayback/Archive] System.Types.TStringDynArray
– RAD Studio API Documentation (documented incorrectly asarray of string
instead ofTArray<string>
.[WaybackSave/Archive] System.Types.TClassicStringDynArray
– RAD Studio API Documentation
Note that not all of the above documentation links are indexed in the corresponding unit pages:
- [Wayback/Archive] System – RAD Studio API Documentation
- [Wayback/Archive] System.Types – RAD Studio API Documentation
--
jeroen