Ian Branch 127 Posted October 1 In which version of Delphi were the uses unit's qualifiers like Vcl. & System. introduced? Share this post Link to post
Dave Nottage 557 Posted October 1 8 minutes ago, Ian Branch said: In which version of Delphi were the uses unit's qualifiers like Vcl. & System. introduced? Delphi 2005 1 Share this post Link to post
Ian Branch 127 Posted October 1 Tks Dave. I didn't realise it was that 'long' ago. ;-) Cheers. Share this post Link to post
Remy Lebeau 1397 Posted October 1 (edited) 2 hours ago, Ian Branch said: In which version of Delphi were the uses unit's qualifiers like Vcl. & System. introduced? They are called Unit Scope Names, not qualifiers. And don't confuse them with Namespaces, which uses a similar naming syntax but different semantics. Here is a useful site: List of Delphi Pascal Features and When Introduced Edited October 1 by Remy Lebeau 1 Share this post Link to post
Ian Branch 127 Posted October 1 2 minutes ago, Remy Lebeau said: And don't confuse them with Namespaces, Perish the thought. 🙂 3 minutes ago, Remy Lebeau said: Here is a useful site: Excellent. Tks. Share this post Link to post
dummzeuch 1505 Posted October 2 Actually, the concept of namespaces was introduced with Delphi 2005, but the RTL and VCL started using them much later. A quick search in my installations found vcl.controls.pas appearing in Delphi XE2, before that it was just controls.pas Share this post Link to post
Rollo62 536 Posted October 2 Usually I try to use fully qualified namespaces only, in the unit and uses definitions. Still I can see that many code may use "partly" or "mixed" qualified namespaces, like this: unit MyCompany.Libs.MyUnit1; uses System.Classes, // Fully qualified name. SysUtils, // Generic name. MyCompany.Libs.Unit2, // Fully qualified name. UnitX; // Generic name. Are there any insights how this behaves, will the resolver of namespaces work on each single name separately and make a separate decision, or will the whole "uses" switched into a different, generic mode? The fully qualified name should be the most performant, and the total generic name should be the least performant, IMHO. What about a mixture of that, is it exactly according to the number of generic name count in those uses, or does it behave worse than that, more like if all where generic names? Share this post Link to post
Peter J 1 Posted October 2 1 hour ago, Rollo62 said: Still I can see that many code may use "partly" or "mixed" qualified namespaces, In XE2 and later, for reasons of backward compatibility I guess, you can get away with not using fully qualified unit scope names for the RTL/VCL etc if you add the required prefixes to project options (Delphi Compiler section, Unit scope names field). Certain default prefixes are added by Delphi when you create a new project. For a new VCL application in Delphi 12.2 I get: Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell That's probably why the "mixed" code works, but it's asking for trouble IMHO. I worry about possible conflicts using default unit scope names, so I usually delete all the default prefixes from project options, which enforces the use of fully qualified scope names. In library code that needs to compile with compilers either side of XE2, where it can't be guaranteed that the user will have any default unit scopes defined, I use something like: {$UNDEF RequiresUnitScopeNames} {$IFDEF CONDITIONALEXPRESSIONS} {$IF CompilerVersion >= 24.0} // Delphi XE3 and later {$LEGACYIFEND ON} // NOTE: this must come before all $IFEND directives {$IFEND} {$IF CompilerVersion >= 23.0} // Delphi XE2 and later {$DEFINE RequiresUnitScopeNames} {$IFEND} {$ENDIF} then in uses statements, for e.g.: uses {$IFNDEF RequiresUnitScopeNames} Windows, Classes; {$ELSE} Winapi.Windows, System.Classes; {$ENDIF} It's a pain, and it's easy to forget to add both versions of a unit name, but it works for me. BTW the $LEGACYIFEND stuff is a work around for problems I encountered with the way $IFEND and $ENDIF work in XE3 and later! Your mileage may vary. 1 Share this post Link to post
Lajos Juhász 293 Posted October 2 On large projects in Delphi XE5 (later they have tried to make it more efficient) Unit scope names have had problems on large projects. the compiler literally tried with every prefix to locate every unit. When I have removed the scope names and changed the source to contain the full unit’s name with scopes, I was able to compile all projects in a project group without a problem. Share this post Link to post
dummzeuch 1505 Posted October 2 You can have a lot of fun when starting to use namespaces. This compiles fine ... unit bla; uses SysUtils; interface implementation procedure Test; begin SysUtils.Abort; end; ... until you add the namespace to the unit name ... unit bla; uses System.SysUtils; interface implementation procedure Test; begin SysUtils.Abort; end; ... but do you really want to write System.SysUtils.Abort ? This is just an example. You don't of course need to qualify Abort, but if there are name clashes in different units you have to, or you can rely on the order of the units in the uses clause, which I think is a bad idea. Share this post Link to post
Rollo62 536 Posted October 4 (edited) On 10/2/2024 at 6:43 PM, dummzeuch said: ... but do you really want to write System.SysUtils.Abort ? But this would run fine too. procedure Test; begin Abort; end; It should be good enough to use fully qualified names only in cases of ambiguity, IMHO. The compiler shows such cases. But in the uses clause I always use fully qualified names. Edited October 4 by Rollo62 Share this post Link to post
Uwe Raabe 2057 Posted October 4 1 hour ago, Rollo62 said: It should be good enough to use fully qualified names only in cases of ambiguity, IMHO. Even then this can be wrapped in a separate procedure (or whatever it is) with a non-colliding name published at a suitable location. When multiple occurrences have to be dealt with, the effort is merely the same with the benefit of better readability. type TWinBitmap = Winapi.Windows.TBitmap; procedure SysAbort; inline; begin System.SysUtils.Abort; end; 1 1 Share this post Link to post
dummzeuch 1505 Posted October 4 10 hours ago, Rollo62 said: But this would run fine too. procedure Test; begin Abort; end; It should be good enough to use fully qualified names only in cases of ambiguity, IMHO. The compiler shows such cases. But in the uses clause I always use fully qualified names. "Abort" is a popular name for procedures and methods, that's why it came to mind. I had to qualify it several times in my code because there was an ambiguity. I'm too lazy to use that qualifier without a good reason. Uwe's answer looks like a good solution for these cases. I hope I remember it the next time this comes up. Share this post Link to post