Watch, Follow, &
Connect with Us
Public Report
Report From:    [ Add a report in this area ]  
Report #:  7174   Status: Reported
VFI Descendants' Uses clause (re-)inserts all VCL Units of Ancestor
Project:   Build #:  7.1.1446.610
Version:    8.0 Submitted By:   Kristofer Skaug
Report Type:  Minor failure / Design problem Date Reported:  2/4/2004 5:30:14 AM
Severity:    Commonly encountered problem Last Updated: 2/9/2004 6:50:52 PM
Platform:    All platforms Internal Tracking #:  
Resolution: None  Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: (1 Total Rating)
5.00 out of 5
Total Votes: 1
(Originally posted as 2779 for D6/D7, but modified for more precise intention):

If you have a VFI descendant unit, Delphi requires its uses clause to include all units of VCL components used by its ancestor, even if the descendant does not add any such components or refer to them explicitly.

As discussed with Danny Thorpe in the closeout of 2779, the main issue here is not the well-meant provision of a "default" uses clause (when a form is first created) with related standard units to help the programmer to easily access commonly used functions and helper classes.

The issue is, that once the programmer has decided he doesn't want or need these extra units (thus manually deleting them), Delphi insists on re-inserting them!!! This is not the case, of course, with most of the "default uses clause" of a blank TForm; this is a specific mechanism of VFI.

As shown by the example Steps, these unit references are not actually required by the compiler to compile successfully, so it would be appreciated if this indiscriminate uses-clause-fudging behavior could be removed.

This "feature" is annoying because it significantly reduces the effectiveness of "Uses clause analysis/purge" tools.
Steps to Reproduce:
In D8 Architect,

1. File | New VCL Forms Application (Project1)

2. On Form1, drop an Indy TIdTCPClient component

3. File | New | Other...
   -> Delphi.NET Projects -> Inheritable Items  
   Select Form1;
   Click OK

4. Now you have a Unit2: (T)Form2 which inherits by VFI from TForm1

5. Compile/Build the project; Note that Unit2 suddenly has
   "IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient..."
   added to its uses clause.

6. Save Unit2 to disk and close it (in the IDE).

7. Using NotePad, edit Unit2.pas from disk by deleting above list of Indy unit
   references in its uses clause, leaving the following result:

unit Unit2;



  TForm2 = class(TForm1)
    { Private declarations }
    { Public declarations }

  Form2: TForm2;


{$R *.nfm}


8. Save and close Unit2.pas from NotePad, and Set both Unit2.pas and Unit2.nfm file attributes to Read-Only.

9. Re-open Unit2 in Delphi IDE and Rebuild the project.
The project compiles fine without the extra uses references.

10. Close Unit2 in Delphi IDE; Remove "Read-only" attribute on Unit2.pas/.nfm.
Re-open Unit2 in Delphi IDE and Rebuild.
The Indy units are back in the uses clause!
(but notably NOT the "default" VCL units such as Forms, Messages, Dialogs...!).

Charles McAllister at 6/1/2006 1:02:34 PM -
I'm experiencing the same problem.  I found your steps easy to follow.  This bug is bothersome to me since I've used a tool to remove all units that are not required to be in the uses clause, but Delphi keeps adding them back.

Kristofer Skaug at 6/29/2006 3:52:42 PM -
Glad to hear some support for this!
Which tool are you using? OPxperts?

Charles McAllister at 6/29/2006 6:31:07 PM -
...removes unused units for delphi 7 projects.
i have added a feature to it so that it will not remove the units that delphi insists on adding.
so i'm not as anxious about getting this report resolved, although i still want Borland to fix it.

Kristofer Skaug at 10/5/2006 1:51:16 PM -
Having unused units in your uses clause makes you more vulnerable to scoping issues, due to the lack of ambiguous scope / duplicate identifier detection / hints in the compiler. See QC1615.

Server Response from: ETNACODE01