Wim ten Brink
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. ;-)
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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(Wind ow: HWnd; List: LParam): Bool stdcall;
begin
TIntegerList(List).Add(Win dow);
Result := True;
end;
...
EnumWindows(@GetAllWindows CallBack, Integer(List))
becomes
function GetAllWindowsCallBack(Wind ow: HWnd; Param: LParam): Bool stdcall;
var
List: TIntegerList absolute Param;
begin
List.Add(Window);
Result := True;
end;
How about this case: Using the "absolute" keyword, I could avoid a typecast in this callback function:
function GetAllWindowsCallBack(Wind
begin
TIntegerList(List).Add(Win
Result := True;
end;
...
EnumWindows(@GetAllWindows
becomes
function GetAllWindowsCallBack(Wind
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 :)
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 :)
ASKER
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. ;-) ]
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. ;-) ]
ASKER
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. :)
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.
ASKER
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... :-)
ASKER
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.