If I have a unit that is filled with constants like...
unit AConsts;
interface
const
Const1 : WideString = 'Const1';
Const2 : WideString = 'Const2';
Const3 : WideString = 'Const3';
Const4 = 100;
Const5 = 100;
implementation
end.
and I want to use this unit from another unit, is there any difference between...
unit AUnit;
interface
uses
AConsts;
Implementation
end.
and
unit AUnit;
interface
implementation
uses
AConsts;
end.
?
The question is not about scope, avoiding circular references etc. It is about differences in the compiled application.
If UnitA
, UnitB
and UnitC
all use AConsts
, would there be a difference in the compiled application (assuming no name clashes between the constants in the AConsts
unit and other code) between App1
where these UnitA
, UnitB
and UnitC
all have AConsts
in the interface section and App2
where UnitA
, UnitB
and UnitC
all have AConsts
in the implementation section.
The difference has to do with where you're allowed to refer to the things that AConsts
has in its interface section. In the first AUnit
, you could use Const4
to declare a fixed-size array in that interface section. You couldn't do that in the second AUnit
because Const4
isn't in scope.
It can have an effect on the compiled program, if you're not careful. Suppose we have another unit that also declares a constant named Const4
:
unit BConsts;
interface
const
Const4 = 50;
implementation
end.
Now we define an array in UnitA
like this:
unit AUnit
interface
uses BConsts;
var
data: array[0..Pred(Const4)] of Integer;
implementation
uses AConsts;
procedure Work;
var
i: Integer;
begin
for i := 0 to Const4 - 1 do begin
data[i] := 8;
end;
end;
end.
That code will write beyond the end of the array because the Const4
that's in scope in the interface section is not the same Const4
that's used in the implementation section. This doesn't happen often with constants. It usually just happens with two identifiers, the FindClose
function defined in Windows
and SysUtils
, and TBitmap
, defined in Graphics
and Windows
. And in those two cases, the compiler will tell you that you've done something wrong, although it won't tell you precisely that you've used an identifier that has two different meanings. You can resolve the problem by qualifying the identifier:
for i := 0 to BConsts.Const4 - 1 do
data[i] := 8;
If all the above precautions are addressed, so your program compiles and runs correctly, then it makes no difference where units are used. In your example with App1 and App2, the two programs will be the same. They won't be identical — the compiler will have processed things in a different order and thus will likely put things in different places — but it will have no effect on the execution of your program.