Jump to content
pyscripter

New Warning in 12.2: Overloading a similar index type by declaring an array property 'Items'

Recommended Posts

The following code (from VirtualTrees) raises a new warning in Delphi 12.2:

  TVirtualTreeColumns = class(TCollection)
    ...

    property Items[Index : TColumnIndex] : TVirtualTreeColumn read GetItem write SetItem; default;
    ...

  end 

The warning says:

[dcc64 Warning] VirtualTrees.Header.pas(280): W1075 Overloading a similar index type by declaring an array property 'Items'
  VirtualTrees.Header.pas(280): Related member: property TVirtualTreeColumns.Items[TColumnIndex]: TVirtualTreeColumn;
  VirtualTrees.Header.pas(280): Related member: property TCollection.Items[Integer]: TCollectionItem;

I get quite a few similar warnings in my code base.

 

Clearly the overwriting (and not overloading) is intentional.    Any ideas of how to get rid of this warning without suppressing it?

 

Edited by pyscripter

Share this post


Link to post
1 hour ago, pyscripter said:

Any ideas of how to get rid of this warning without suppressing it?

You mean without using {$WARN}? Have you looked in the project settings to see if there's an option there to disable it?

Share this post


Link to post

AFAIK, there is no legal syntax to avoid this warning. The only way I know of is locally suppressing it:

    ...
{$WARN OVERLOADING_ARRAY_PROPERTY OFF}
    property Items[Index : TColumnIndex] : TVirtualTreeColumn read GetItem write SetItem; default;
   ...
 end;
{$WARN OVERLOADING_ARRAY_PROPERTY DEFAULT}

 

  • Thanks 2

Share this post


Link to post
1 hour ago, Uwe Raabe said:

{$WARN OVERLOADING_ARRAY_PROPERTY OFF}

Will this not cause an issue with earlier DELPHI versions?

  • Like 1

Share this post


Link to post
13 minutes ago, pyscripter said:

Will this not cause an issue with earlier DELPHI versions?

No issue there, just simple error.

Quote

[dcc32 Error] uMain.pas(74): E1030 Invalid compiler directive: 'OVERLOADING_ARRAY_PROPERTY'

 

  • Thanks 1

Share this post


Link to post

I have the same problem with two units in ICS, so have added alternative NativeInt versions of the Items property for D12.2 and later.  

 

Angus

Share this post


Link to post
1 hour ago, Kas Ob. said:

No issue there, just simple error.

Great.   Swap a warning in 12.2 with an error in earlier versions.  

Edited by pyscripter
  • Like 1

Share this post


Link to post
1 hour ago, Angus Robertson said:

have added alternative NativeInt versions of the Items property for D12.2 and later

Could you please give an example of what you did?

Share this post


Link to post

Assuming the warning relates to TList,Items[Index] changing from Integer to NativeInt, I created alternative versions of the SetItem and GetItem functions with NativeInt.

 

Our library needs to support older versions like 12.1 without warnings so DEFINES for 12.2 and later complicate it, you can probably just change a few Integers to NativeInt.

 

Angus

  • Like 1

Share this post


Link to post
22 minutes ago, Angus Robertson said:

Assuming the warning relates to TList,Items[Index] changing from Integer to NativeInt, I created alternative versions of the SetItem and GetItem functions with NativeInt.

 

Our library needs to support older versions like 12.1 without warnings so DEFINES for 12.2 and later complicate it, you can probably just change a few Integers to NativeInt.

 

Angus

Aha!  So is the type of the indexed property that the compiler complains about and not just the fact that you overwrite the inherited indexed property!   And it is the change of Integer to NativeInt that caused that.

Share this post


Link to post

 

Interestingly the build dialog box reports this as 3 warnings!

Screenshot 2024-09-12 214216.png

 

Edited by pyscripter

Share this post


Link to post
11 hours ago, Kas Ob. said:

No issue there, just simple error.

 

 

I use this to make code compatible to previous versions.

 

{$IFDEF VER360}
  {$IF Declared(RTLVersion122)}
    {$WARN OVERLOADING_ARRAY_PROPERTY OFF}
  {$IFEND}
{$ENDIF}
 

  • Like 1

Share this post


Link to post
43 minutes ago, Jaska said:

{$IFDEF VER360}
  {$IF Declared(RTLVersion122)}
    {$WARN OVERLOADING_ARRAY_PROPERTY OFF}
  {$IFEND}
{$ENDIF}

This warning/error is here forever, i suggest to do yourself a favor and rewrite the above with future proof parameters.

  • Like 1

Share this post


Link to post
7 hours ago, Kas Ob. said:

This warning/error is here forever, i suggest to do yourself a favor and rewrite the above with future proof parameters.

I ended up with the following, which is backward compatible and future proof:

    {$IF (CompilerVersion > 36) or Declared(RTLVersion122)}{$WARN OVERLOADING_ARRAY_PROPERTY OFF}{$ENDIF}
    property Items[Index : TColumnIndex] : TVirtualTreeColumn read GetItem write SetItem; default;
    property Header: TVTHeader read FHeader;
    property TrackIndex : TColumnIndex read FTrackIndex write FTrackIndex;
    property TreeView : TCustomControl read GetTreeView;
    property UpdateCount;
    {$IF (CompilerVersion > 36) or Declared(RTLVersion122)}{$WARN OVERLOADING_ARRAY_PROPERTY ON}{$ENDIF}
end;

Notes:

  • If the $WARN OFF comes immediately after the Items declaration you still get the warning.
  • Delphi 12.2 still defines RTLVersion121.  Presumably if there is a Delphi 12.3 etc.  RTLVersion122 will be defined.
Edited by pyscripter
  • Like 2

Share this post


Link to post
19 minutes ago, pyscripter said:

Delphi 12.2 still defines RTLVersion121.  Presumably if there is a Delphi 12.3 etc.  RTLVersion122 will be defined.

I have checked this on D11.2 there is also both RTLVersion111 and RTLVersion112 defined.

  • Like 1

Share this post


Link to post
11 hours ago, Jaska said:

I use this to make code compatible to previous versions.

 

{$IFDEF VER360}
  {$IF Declared(RTLVersion122)}
    {$WARN OVERLOADING_ARRAY_PROPERTY OFF}
  {$IFEND}
{$ENDIF}
 

VER360 and RTLVersion12x are specific to the D12.x series and won't be declared anymore once D13.x+ is released.  So this is not future-proof.

 

Edited by Remy Lebeau

Share this post


Link to post
On 9/12/2024 at 9:16 PM, Angus Robertson said:

Assuming the warning relates to TList,Items[Index] changing from Integer to NativeInt, I created alternative versions of the SetItem and GetItem functions with NativeInt.

I am afraid is not that simple.   I did the same and when I tried to compile with Delphi 11 64bits, I got compilation errors, not in the declaration but when using the TObjectList descendent.   

 

Apparently Delphi implicitly supports indexed property overloading!  Hence the name of the warning.    Did you know that?  I didn't.

Example:

 

  TSynEditMarkList = class(TObjectList)

    ...
    function IsBookmark: Boolean;
    property Items[Index: NativeInt]: TSynEditMark read GetItem write SetItem; default;
  end;
  
  MarkList: TSynEditMarkList;
  
  var 
    I: Integer;
    J: NativeInt
    
    // Both indexed properties, the one defined here and the inherited one can be used as default properties.
    Mark[I].IsBookmark; //  error message IsBookmark is not recognized.  Mark[I] is a TObject as in the inherited class.
    Mark[J].IsBookmark; // works
    

 

I will probably end up using a generic TList to avoid this mess.

Edited by pyscripter

Share this post


Link to post
1 hour ago, pyscripter said:

Did you know that?

Yep! I first made use of that almost 10 years ago in a class holding translation strings. Before that the strings were indexed by an Integer, but later we extended that to string indices.

   property Items[Index: Integer]: string read GetItems; default;
   property Items[const Index: string]: string read GetItems; default;

The interesting part was that both are marked as default properties, which allowed us to simply write something like this:

Label1.Caption := Translations[42];
Label2.Caption := Translations['Error'];

The most benefit came from the fact that we could keep the Integer based translations and simply add the string based ones - all using the same Translations instance.

Edited by Uwe Raabe
  • Like 2

Share this post


Link to post
Quote

I got compilation errors, not in the declaration but when using the TObjectList descendent. 

I only updated two ICS components derived from TList, not TObjectList with NativeInt, by creating a new {$DEFINE TListNatInt} for 12.2 and later, and then using conditional code, tested in 1.2 and 11.3, TObjectList may need a different approach. 

 

Angus

 

Share this post


Link to post
1 hour ago, Angus Robertson said:

{$DEFINE TListNatInt}

So, one approach is to do something like:

{$IF (CompilerVersion >= 35)
  TListSize = NativeInt;
{$ELSE}
  TListSize = Integer;
{$END}

 

and then something like:

 

  TSynEditMarkList = class(TObjectList)

    ...
    property Items[Index: TListSize]: TSynEditMark read GetItem write SetItem; default;
  end;

This would make sure that in all versions of Delphi you do not overload the array property but instead overwrite it.  Unintentionally overloading the array property is likely to cause trouble (see earlier post).  It also needs just one conditional compilation directive for the whole code base.

 

Edited by pyscripter

Share this post


Link to post

There are several ways of fixing the TList change, your conditional check would not work for Delphi 7 or Delphi 12.1, as has been explained earlier in this topic, and I prefer not to have too many special types in libraries, makes them harder to understand.  You also need to change the setters,

 

Angus

 

Share this post


Link to post
22 hours ago, pyscripter said:

So, one approach is to do something like:


{$IF (CompilerVersion >= 35)
  TListSize = NativeInt;
{$ELSE}
  TListSize = Integer;
{$END}

 

and then something like:

 


  TSynEditMarkList = class(TObjectList)

    ...
    property Items[Index: TListSize]: TSynEditMark read GetItem write SetItem; default;
  end;

This would make sure that in all versions of Delphi you do not overload the array property but instead overwrite it.  Unintentionally overloading the array property is likely to cause trouble (see earlier post).  It also needs just one conditional compilation directive for the whole code base.

 

I'm using your suggestion, but using CompilerVersion>=36 (Delphi 12), so the correct syntax is:

{$IF (CompilerVersion >= 36)}TListSize = NativeInt;{$ELSE}TListSize = Integer;{$IFEND}

  • Thanks 1

Share this post


Link to post

You still need   {$IF Declared(RTLVersion122)}  if you want the component to also work on 12.0 and 12.1.   And $IF is not supported on earlier compilers, if that matters.

 

Angus

 

Share this post


Link to post
1 hour ago, Angus Robertson said:

You still need   {$IF Declared(RTLVersion122)}  if you want the component to also work on 12.0 and 12.1.

No you don't.  The index was changed to NativeInt in Delphi 12.0.  There are no interface changes in minor versions. It is just the warning that was added in 12.2.

Regarding older versions,  you are right if you need to support versions before IF was introduced.  But many of us including @Carlo Barazzetta don't.

Edited by pyscripter

Share this post


Link to post
15 minutes ago, pyscripter said:

if you need to support versions before IF was introduced

IIRC, that has been Delphi 6 or 7. One can even test for that with {$IF CONDITIONALEXPRESSIONS}.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×