Delphi: Which are the downsides of having unused units listed in the uses clause?
The biggest problem, to my mind, is that you can sometimes get caught out by Delphi scoping rules. If you have two identifiers with the same name in different units, then using this name refers to the one declared in the unit declared latest in the uses clause.
If you suffer from a problem due to this you can always fully specify the identifier. What I would really love to see would be compiler warnings to tell you if you are naming an identifier that whose identity is only determined by this latest declaration in uses clause scoping rule.
Delphi smart linker will ignore unused code so normally the presence of these "extra" units does not increase the size of the compiled program.
Here are some points i get from this link about downsides of unused units
- Cleaner code to maintain, no need to bother about code that is not used
- Code from initialization and finalization sections in unused units is not linked in
- Compilation runs smoother and quicker
No. In general smartlinking works like this:
- If you use an unit somewhere, at least the inialization and finalization code is linked in.
- In principle, only the functions/methods that you actually use, directly or indirectly from the main program (.dpr) are linked in.
- Some bits that are reachable via RTTI will also be linked in. Rule of thumb is that RTTI for enums is always linked in (if you use the enum), and that (as soon as you construct a class), everything published, or reachable via published properties is linked in.
- Keep in mind that the initialization of unused units might pull in dlls or even whole frameworks of dlls (like .NET) that might be an unnecessary complication ofdeployment.
- (As Rob says in the comments) Resources are another factor that are always linked in, since due to their runtime usage the compiler can't determine if they are used or not.
- in DLLs or package projects, all published symbols will be linked in, since an external program might call them.
Conclusion: the final .exe size is determined
- mostly by anything reachable by above roots (mainprogram, initialization,finalization,RTTI of classes that can be constructed),
- some bits that are always linked in if the unit is USED (resources, certain forms of RTTI like enums),
- language helpers in the RTL, like ansistring helper routines, most of these are in System, some might be in variants.
- Some relative small internal program administration (e.g. tables with units that determine initialization/finalization order), tables needed for resource handling, DLL linking etc.
- Debug info (if TD32 on)
- compiler settings like optimization and runtime checks also mildly influence binary size.
- Binary compression utils like UPX. I don't recommend these though, since in my experience they constantly cause problems.
Free Pascal roughly works in the same way, the defaults are just different; Debug is currently nearly always "in binary" (like TD32), and in snapshots, smartlinking is off by default. (in official releases it is on though).
Moreover one must not lose sight of the magnitude. Strutils in its entirety is like 15kb max.
(update 2011-11-01)
Got a remark from sb on this reply I liked to share:
Basically he shed doubt on the remark that enums are always linked in. Maybe the registering of a class that has a published property of the enum type drags them in. The reasoning makes sense, but I haven't tested it yet. So RTTI of enum directly can be only linked if typeinfo(tenumtype) is queried somewhere, or if it is used in a published section of the class which is used. (directly or typeinfo(theclass) is queried)