Home > Delphi, Object Pascal > Delphi and the absolute keyword

Delphi and the absolute keyword

There is a lot of hidden gems in the Delphi environment and compiler, and while some might regard the “absolute” keyword as obsolete, I could not disagree more; in fact I find it to be one of  the most useful,  flexible aspects of Delphi (and object pascal in general).

The absolute keyword allows you to define a variable of a specific type, yet instruct the compiler that it should use the memory of another variable. I  cannot stress how useful this can be when used right, and how much cleaner it can make code that deal with different classes or types – that are binary compatible.

Tab pages revisited

Unlike most I try to avoid the form designer when I can. Im not purist about it, I just find that inheriting out your own controls and augmenting them results in significantly faster code, as well as a fine grained control that ordinary DFM persistence can’t always deliver.

For example: Lets say you have inherited out your own TPageControl. You have  also inherited out a few TTabSheet based classes, populating the tabsheets during the constructor – so there is no design data loaded – resulting in faster display time and a more responsive UI.

In one of my events, which is called as TabSheet class is created, allowing me to prepare it, like set the icon glyph for the  tab, its caption and so on – the absolute keyword makes my code faster (since there is no type-casting) and more elegant to read.

All I have to do is check for the type, and once I know which type it is, I use the variable of that type that share memory with the initial type, TTabSheet. Like this:

absolute

Obviously this is not a live example, its written like this purely to make a point. Namely that the Page parameter can be accessed as a different type without allocating variables or typecasts. Im sure there are some memory use, but i find the above more elegant than 3 x nested if/then/else before you can even touch the pointer.

While this is just a small, miniscule -bordering on pseudo example, the use of absolute can help speed up intensive code by omitting typecasts. Perhaps not above, but in other, more intensive routines dealing with graphics.

It is actually a tremendous help when dealing with low level data conversion (like dealing with 8, 15, 16, 24 and 32 bpp data. When you call routines thousands of times, every bit helps – and absolute is one of those keywords that saves a few cycles per use.

Absolute is definitely one of Delphi’s un-sung heroes. But it’s a scalpel, not a chainsaw!

  1. Gerry Coll
    July 16, 2020 at 3:56 am

    In pre-generics Delphi I would sometimes use
    var
    p: Pointer;
    obj: TMyObject absolute p;
    begin
    for p in FlIst do
    begin
    obj.DoSomeThing;
    end;

    The other place they are useful is in sort comparators:
    function CompareMyObjects(Item1, Item2 : pointer) : integer;
    var
    Obj1 : TMyObject absolute Item1;
    Obj2: TMyObject absolute Item3;

  2. Aljosa Skocir
    July 16, 2020 at 7:07 am

    Never thought about usage of absolute in this way. Thanks for the very useful example. Your example above could easily be an official Delphi example on how to use keyword absolute and latter explained that it’s not only limited to that. That way users could immediately see the whole idea behind it.

  3. abouchez
    July 16, 2020 at 10:33 am

    It is not so simple. In practice, using “absolute” forces the Delphi compiler to store the pointer on the stack: it needs a location to be “absolute”. If you use local TEditTab and TTFormTab temporary variable, and assign the TPage to it, the generated asm it may actually be faster, since it is more likely to be implemented as a register.
    In your code, the slow part is definitively the two “is” evaluations. Using tag or a inherited common inherited field with a “case” would be faster.
    Anyway, in SOLID code, using cascaded “is” or “case” is an anti-pattern. A virtual method assigning the methods is a cleaner – and also faster approach. But for VCL, it is hard to create such virtual methods.
    Back to the subject. No, “absolute” is no magic bullet. I use it just like “with”, for small part of the code, just one or two lines, not more.

    • July 16, 2020 at 5:24 pm

      Its meant to demonstrate a concept. Nobody writes it like that. The point of the example is to show that you access the same memory (in this case the incoming Page parameter) from two different vantage points (read: types) through absolute.
      This saves time and is very fast when dealing with raw pixel data, where you (for example) get a longword pointer in, but it can in fact be a word or even a byte depending on the mode. Instead of having separate variables + typecasts for each, you can wire up the “mapping” via absolute, resulting is fast code and far more elegant code in my view.
      When something says “for example”, its usually just to render to the reader “possibilities”, not absolutes.

  4. abouchez
    July 16, 2020 at 5:44 pm

    You missed the main point. It was that “absolute” will avoid the possibility of the compiler to use a register. It will always use a stack variable for the “absolute” pointer. This is what I have seen with the Delphi compiler.
    Such a local stack variable will be slower e.g. than a variable record pointer, which still may use a register for the pointer. When processing raw pixel data, you will find a speed penalty of “absolute” instead of a pointer to a variable record. A variable record is very efficient in such case – and of course, SSE/AVX instructions would be magnitude faster for pixel process.
    For me, “absolute” is no hero, just sometimes a convenient shortcut in code, just like “with”.

    • July 16, 2020 at 7:04 pm

      Maybe we bypassed each other. I see your point. Just meant that its just an example. I shun with as the plauge tho 🤣

  5. Nikolaj Henrichsen
    July 16, 2020 at 7:23 pm

    I’d write:
    TEditTab(Page).OnChanged := HandleTabChanged;

    Same performance and no need to declare local vars.
    Correct me if I’m wrong 🙂

    • July 16, 2020 at 7:45 pm

      As would i. It was a 10 second brainfart to show how absolute could be used 🙂

  6. Ozz Nixon
    November 9, 2020 at 6:43 pm

    You may have intended this to be “its just an example”. However, too many programmers are lemmings, they will see your “example”, and start strategizing ways to use it in their code, not realizing it is poor practice and produces poor performance. As a person posting anything on the Internet, you must take ownership for leading people the wrong way. Maybe adding to the topic “you should avoid doing this in your own code”.

  7. Craig Chapman
    April 14, 2021 at 3:21 pm

    As others have commented, explicit type casting would probably perform at the same rate – none the less, it’s an interesting idea. Some have commented that this would be bad practice for various reasons (declaring additional local vars, or it isn’t obvious what it does etc)… but I wonder if pascal actually offered syntax to do this in a more obvious way, if that would stand true. f.x….

    var
    a: TEdit;
    b: a as TMyEdit;

    This might actually be a nice syntax feature if done right, offering an explicitly stated means of casting while avoiding the syntactic bloat of explicit casting.

  1. No trackbacks yet.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: