* * *

Author Topic: The wiki page for "constref" doesn't really make sense.  (Read 1522 times)

Akira1364

  • Sr. Member
  • ****
  • Posts: 363
The wiki page for "constref" doesn't really make sense.
« on: October 30, 2017, 01:27:21 am »
Currently it says:

"The new feature notes for version 2.6 suggest that you should only use this for interfacing with external routines in other languages, where this type of parameter passing is required."

Notwithstanding the fact that it's referring to a now rather outdated FPC version, I'm unsure as to what this was even supposed to refer to or mean in the first place. It makes it sound like constref is some dangerous keyword that should be generally avoided.

In reality, using constref is the only way to guarantee that you actually get the optimizations when passing record types into functions or procedures that normal const is supposedly meant to enable (but in my experience only does very rarely.)

Compile with -a and look at the generated assembly, if you don't believe me. Constref will always result in significantly less lines of code when passing records, whereas const only will sometimes if at all.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 4807
    • wiki
Re: The wiki page for "constref" doesn't really make sense.
« Reply #1 on: October 30, 2017, 01:47:56 am »
First of all you are comparing the "current implemented behaviour" (of whatever version of fpc?) with the "documented design"

So it may well be that in the fpc version that you tested (or even all fpc versions available so far), for specific code you get better results.

But that may not hold true for future versions.

Below is not tested...

constref will always pass a parameter as pointer, even if the parameter could be passed as value in a register.

And the latter (value in register) is certainly preferable.

Imagine the following
Code: Pascal  [Select]
  1. type TFoo: record a: pointer; end;
  2. var x: Tfoo;

such a record makes x assignment incompatible to other pointers. So there are usecases for it. (operator overloading)

If you then have
Code: Pascal  [Select]
  1. procedure takesFoo(constref a: TFoo);

This will be more expensive than "const a: TFoo".

On the calling side, it could go either way. Maybe on the calling site constref will save a statement. (maybe in a future fpc it will be different)

But inside takesFoo the variable "a" is a pointer to TFoo.
Accessing a now needs an extra pointer dereference.

If "a" can not be kept in a register (because takesFoo is to complex), then the overhead of accessing the value via a pointer may happen many times in takesFoo.


------------
Quote
Constref will always result in significantly less lines of code when passing records

I assume that is on the calling side?

How about on the called site, when dereferencing the pointer is added?

-----------
Also you need to say:
Optimize for size or speed?

Sometimes code with a few extra lines, is faster than that with less.

« Last Edit: October 30, 2017, 01:49:54 am by Martin_fr »

Akira1364

  • Sr. Member
  • ****
  • Posts: 363
Re: The wiki page for "constref" doesn't really make sense.
« Reply #2 on: October 30, 2017, 04:22:29 am »
Well, if you re-read my post you'll see I was specifically referring to records. Passing classes with constref actually has the opposite of an optimal effect, I've found, and tends to lead to massive bloat in the generated code.

Also:

constref will always pass a parameter as pointer, even if the parameter could be passed as value in a register.

Is that actually how it's intended to work? Because it certainly doesn't seem to work that way in practice (with records, again) in FPC 3.0.0+/trunk.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 4807
    • wiki
Re: The wiki page for "constref" doesn't really make sense.
« Reply #3 on: October 30, 2017, 05:20:42 am »
Well, if you re-read my post you'll see I was specifically referring to records. Passing classes with constref actually has the opposite of an optimal effect,
Nobody was talking about classes? I certainly was not. I was only talking about records.

Quote
constref will always pass a parameter as pointer, even if the parameter could be passed as value in a register.

Is that actually how it's intended to work? Because it certainly doesn't seem to work that way in practice (with records, again) in FPC 3.0.0+/trunk.
Example?

The exact term is "passing by ref". However a ref(-erence) is a pointer in this case.
It is a hidden pointer. So you do not need (and are not allowed) to dereference it in your code. The compiler will magically add the dereferencing.

Also keep in mind, that "passing by ref" is only half the story. It also has all the restrictions of a "const param" applying do it. Remember: A "const param" is NOT enforced by the compiler. It is you telling the compiler that you will NOT change the value.


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 4807
    • wiki
Re: The wiki page for "constref" doesn't really make sense.
« Reply #4 on: October 30, 2017, 05:53:57 am »
The wiki article was incomplete and misleading.
I changed it. (It's still not perfect).
http://wiki.lazarus.freepascal.org/Constref

First is the common wrong statement that const/constref make the parameter unchangeable. (Yes they do, but that is a side effect)
Since the parameter either is by ref (constref) or may be by ref (const), changing the variable that is passed as the parameter is equal to changing the parameter. And therefore the variable is not allowed to be changed. Doing so can crash the program.

"use only for ... ext routines" is also wrong. Of course it can be used for anything you want. It just may not be as optimal.

It can on one platform for one target cpu, with a specific fpc version be a good deal more effective. The optimizer in FPC is still subject to future improvements.
You just must be aware, that if you change fpc version or cpu target or surrounding code in your app, then optimizations could be different.

« Last Edit: October 30, 2017, 05:58:24 am by Martin_fr »

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus