Link to home
Start Free TrialLog in
Avatar of Wim ten Brink
Wim ten BrinkFlag for Netherlands

asked on

[Discussion] The absolute keyword...

Okay, I guess not many of you have ever heard of this keyword. It might be that I'm actually the only developer who is actually using it anyways. So let's start a discossion about if it's a useful keyword or not...

So, when do I use it? Well, I have a unit that generates log information to a text file. This unit CP_Debug contains this line:

var Log: TextFile;

Plain and simple. The Initialization part creates the file, the finalization parts closes it. In-between I just do lots of WriteLn(Log, ...); to it, thus it generates some interesting information for me to use while debugging. But what I've done in another unit untComponent is put this line of code:

var Log: TextFile absolute CP_Debug.Log;

Now you see how absolute is used. :) Basically, it tells that the variable Log in untComponent is located at the same location as the variable Log in CP_Debug. Which is very interesting but it still doesn't show you the advantage of using this trick.

Well, the advantage is in the third unit I create. In unit frmMain I've this uses clause:

uses untComponent;

And now the big trick... In frmMain I can now use WriteLn(Log, ...); statements that will write to the log file in a unit that is basically invisible for the frmMain unit! I do not have to add the CP_Debug unit to the frmMain unit, keeping the uses clause smaller and thus easier to read. I could even be funnier and add to frmMain this line:

var Log: TextFile absolute untComponent.Log;

And then all units that use frmMain can write to a textfile defined in a faraway unit that they're not even aware of! Well, pretty powerful, isn't it? Basically, it allows you to "forward" global variables to other units.

Okay, now... It's a nice trick but do you consider this a neat trick or would you never even dare to use it? Is it proper to write software like this? The points will go to the one with the best arguments. ;-)
SOLUTION
Avatar of gary_williams
gary_williams

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Wim ten Brink

ASKER

True... The absolute keyword allows some nasty code to be created. But there's a difference between using it to access one memory space as different types of date or, as in my example, as an alias to another unit. I often end up with lots of small units and to keep my uses clause more readable, I do quite a few classtype aliases in my code, so I can create wrapper units around the smaller ones. Better to have "uses wrapper;" than "uses unit1, unit2, unit3, unit4, unit5, unit6;" in my code.
But AFAIK, the absolute keyword can only be used for global variables, not local variables. Trashing the stack is not possible. You could however read garbage but you have the same risk with an invalid typecast... Besides, variant records just provide the same risk factor. You could define something as Integer in one branch and Extended in the other.
Avatar of gary_williams
gary_williams

You can use absolute with two local variables, or a local variable and a procedure argument, with no problem.

How about this case: Using the "absolute" keyword, I could avoid a typecast in this callback function:

function GetAllWindowsCallBack(Window: HWnd; List: LParam): Bool stdcall;
begin
  TIntegerList(List).Add(Window);
  Result := True;
end;
...
    EnumWindows(@GetAllWindowsCallBack, Integer(List))


becomes

function GetAllWindowsCallBack(Window: HWnd; Param: LParam): Bool stdcall;
var
  List: TIntegerList absolute Param;
begin
  List.Add(Window);
  Result := True;
end;
A variant record is as big as the biggest member so trashing memory should be impossible.
never used it but I might occasionally :)
for abstraction and isolation I'm into interfaces .. leaning as much as I can to OOP
will just follow the discussion .. it's interesting enough :)
Robert is correct here, though. If you use:

var
  B: Byte = 0;
  BB: Byte = 0;
  I: Int64 absolute B;
begin
  I := $FFFFFFFFFFFFFFFF;
  WriteLn(BB);
end.

Then BB will be 255, not the 0 that it was initialized to. In fact, this does make the absolute keyword a bit risky if you change the datatype. Still, my point is that it's useful as an alias thus with continuously maintaining the same datatype. Still Robert has a good argment for NOT using it. :)
[We could also start a discussion about the goto statement too since quite a few people have banned this too, while others do consider it useful if properly used. But I fear that might lead to online battles. ;-) ]
Well, I guess the discussion ended here. The question was originally 50 points but I'll increase it.

50 points for Robert, since he gave good reasons not to use it.

Another 30 points for Gary for his further explanation of the keyword, although I was familiar with this usage too. Still, useful for the EE archive. Your idea of using absolute in local variables is interesting but won't work. Besides, a simple typecast works just as well. :)
I'm not sure what you mean by "using absolute in local variables ... won't work".  It compiles and runs without error.
Geez. I never expected that it would run in local variables. Then again, in the old Turbo Pascal, you couldn't use absolute that way, if I'm not mistaken... :-)