Recent

Author Topic: const and constref  (Read 4254 times)

munair

  • Hero Member
  • *****
  • Posts: 781
  • compiler developer @SharpBASIC
    • SharpBASIC
const and constref
« on: November 28, 2021, 09:27:26 am »
As I'm making string parameter considerations for the SharpBASIC compiler, I wonder what's the real benefit of constref.

A string can be passed (implicitly) by reference, in which case a descriptor is passed, or if a parameter is declared as a const the string address itself is passed. This means that if a constant string is passed as a parameter not declared as const, it should not be allowed (Pascal case?), or a temporary copy with descriptor could be passed.

Either way, if const and constref both pass strings that cannot be changed inside the procedure, why have constref?
« Last Edit: November 28, 2021, 11:10:40 am by munair »
keep it simple

ASerge

  • Hero Member
  • *****
  • Posts: 1900
Re: const and constref
« Reply #1 on: November 28, 2021, 10:50:46 am »
This means that if a constant string is passed as a parameter not declared as const, it should not be allowed (Pascal case?), or a temporary copy with descriptor should be passed.
A temporary copy is created inside the procedure. If you haven't explicitly declared the parameter as const, then for managed types it means something like this:
Code: Pascal  [Select][+][-]
  1. procedure Proc(P: string);
  2. var
  3.   PAlias: string = P;
  4.   // For an immutable value of P, a copy will be created in the heap
  5.   // For other cases, just the ref counter will be increased
  6. begin
  7.   // Inside Proc PAlias used instead of P
  8.   try
  9.     // Proc code
  10.   finally
  11.     PAlias := nil;
  12.   end;
  13. end;
  14.  

Either way, if const and constref both pass strings that cannot be changed inside the procedure, why have constref?
There is no difference in the current implementation for strings.

ccrause

  • Hero Member
  • *****
  • Posts: 527
Re: const and constref
« Reply #2 on: November 28, 2021, 10:51:24 am »
Good question, especially considering that constref[ isn't described in the documentation.  From the feature announcement it seems as if the main motivation was to have compatibility with C's const * parameters.

My interpretation of the difference between const and constref is that a const parameter can be passed either by value or by reference (it is up to the compiler to decide), while constref forces the compiler to pass a reference to the parameter.

While there may not be a difference currently for passing string parameters, it may change the way other parameter types are passed.

440bx

  • Hero Member
  • *****
  • Posts: 2623
Re: const and constref
« Reply #3 on: November 28, 2021, 11:04:11 am »
Your questions are valid but, I'd suggest you think about it a different way.

Instead of thinking of a string as a Pascal string, think of it as just a block of memory (larger than fits in a register) without anything special about it (like being a Pascal string that is a native type in FPC/Delphi.)

Normally, if some type that is a block of memory is passed by value then the compiler makes a copy of it (usually on the stack) and passes the address of that copy to the caller.   That way whatever changes are made to it disappear when the caller returns (as it should since the parameter was passed by value.)  Note that, with only rare exceptions, any structure that doesn't fit in a register is going to be passed by address even if no changes will be made to the structure by the caller, simply because the structure does not fit in a register.

The critical difference between const and constref is that, const does not imply that the parameter will be passed by reference, it can be passed by value (provided it fits in a register) and enforce that it not be written to by "marking" it const.

Constref on the other hand, explicitly requires the parameter to be passed by reference (even if it would fit in a register and could be passed by value) and, tells the compiler that in spite of being passed by reference, no writing to that parameter is allowed.  That is enough for the compiler to pass a reference to the structure _without_ having to make a copy of it on the stack (to ensure the original is unchanged.)

IOW, const MAY end up passing a parameter by reference (depends on the parameter's size) whereas constref will ALWAYS pass the parameter by reference regardless of its size.

I guess you're asking because you plan on supporting strings in SharpBasic. right ?

PS: pretty much what @ASerge and @ccrause stated while I was typing this post.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

munair

  • Hero Member
  • *****
  • Posts: 781
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: const and constref
« Reply #4 on: November 28, 2021, 11:26:44 am »
I guess you're asking because you plan on supporting strings in SharpBasic. right ?

That's right and I'm already half-way through. Currently in SB a variable or fixed-length string has a descriptor, whereas a constant is just an address to a null-terminated string. Preferably, when passing a string to a procedure, no copy is made and it is enough for the compiler to know if it is a const (string-address) or otherwise (descriptor). An explicit const can simply pass the string address (even if the string passed is not const), except for fixed length strings, which have the size in the descriptor, in which case (the only case I can think of) it could be implicitly passed as const-ref.
keep it simple

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 9768
  • FPC developer.
Re: const and constref
« Reply #5 on: November 28, 2021, 06:29:57 pm »
As far as I understood it, the CONST meaning of most architecture's ABIs can vary on if a structure is passed by reference, copied on the stack first and then by value, or passed in registers etc. Also, the cutoffs ( structs under <xx> bytes by value, larger by reference) can vary.

However in the original x86 ABI this meant it was mostly passed by reference. This lead to heaps of Delphi (and FPC) x86 only code assuming that CONST meant by-ref, even if that was in violation of the ABI of architectures that had more registers for parameter passing (like PPC 64)

Constref is mostly for the case some code forcedly needs CONST to be by ref, like the above old x86 only code.

CONST is redefined as being ABI compliant, and the exact meaning might thus vary with architecture.

munair

  • Hero Member
  • *****
  • Posts: 781
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: const and constref
« Reply #6 on: November 28, 2021, 10:31:26 pm »
As far as I understood it, the CONST meaning of most architecture's ABIs can vary on if a structure is passed by reference, copied on the stack first and then by value, or passed in registers etc. Also, the cutoffs ( structs under <xx> bytes by value, larger by reference) can vary.

However in the original x86 ABI this meant it was mostly passed by reference. This lead to heaps of Delphi (and FPC) x86 only code assuming that CONST meant by-ref, even if that was in violation of the ABI of architectures that had more registers for parameter passing (like PPC 64)

Constref is mostly for the case some code forcedly needs CONST to be by ref, like the above old x86 only code.

CONST is redefined as being ABI compliant, and the exact meaning might thus vary with architecture.

Makes sense.
keep it simple

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 748
Re: const and constref
« Reply #7 on: November 29, 2021, 09:31:48 am »
In most cases these are useful for external routines only. No difference, except may be extra stack consumption, inside Pascal routines, as you can't write anything to such variables anyway. In most cases it's important for managed types only or types, that require some sort of conversion. For example for string, that requires string -> PChar conversion. Using const - is hint for compiler, that data in temporary PChar representation won't be changed by external routine, so no back conversion is needed.
29.12.2021 - migration to DynamicData 4.1 is completed - complete overhaul of data access driver.
My project still requires full Delphi 2009 support to be ported to Lazarus.
It's time to finally do it, because Delphi 2009 is 12 years old.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 9768
  • FPC developer.
Re: const and constref
« Reply #8 on: November 29, 2021, 10:46:23 am »
Note that for Pascal level strings it also matters for refcounting.


 

TinyPortal © 2005-2018