What difference does it make when I use "const" in a procedure's parameter?

13,110

Solution 1

Looking at the documentation states:

"Using const allows the compiler to optimize code for structured - and string-type parameters. It also provides a safeguard against unintentionally passing a parameter by reference to another routine."

In case of a string for example the optimization means there is no additional refcounting when passing as const. Also passing as const does not mean it's a copy. Often it internally passes as reference because the compiler ensures no write access to it.

Some very interesting articles to completly understand what's going on under the hood:

http://delphitools.info/2010/07/28/all-hail-the-const-parameters

http://vcldeveloper.com/articles/different-function-parameter-modifiers-in-delphi

Edit:

A simple example to show that const may result in pass by reference internally:

program Project1;

{$APPTYPE CONSOLE}

type
  PMyRecord = ^TMyRecord;
  TMyRecord = record
    Value1: Cardinal;
    Value2: Cardinal;
  end;

procedure PassAsConst(const r: TMyRecord);
begin
  PMyRecord(@r).Value1 := 3333;
  PMyRecord(@r).Value2 := 4444;
end;

procedure PassByVal(r: TMyRecord);
begin
  PMyRecord(@r).Value1 := 3333;
  PMyRecord(@r).Value2 := 4444;
end;

var
  r: TMyRecord;
begin
  r.Value1 := 1111;
  r.Value2 := 2222;
  PassByVal(r);
  Writeln(r.Value1);
  Writeln(r.Value2);

  PassAsConst(r);
  Writeln(r.Value1);
  Writeln(r.Value2);

  Readln;
end.

Solution 2

When you don't have the const prefix, the compiler has to assume that you will be changing the parameter. That means copying it and setting up a hidden try...finally to dispose of the local string variable, so sometimes the const can yield a significant performance improvement. It also makes the generated code smaller.

Solution 3

In addition to the previous answers of efficiency when using a const (i.e. the compiler does not need to copy the variable), if you use a const with an Interface parameter, it prevents the triggering of ref counting.

Share:
13,110
Jerry Dodge
Author by

Jerry Dodge

I'm a Delphi developer. I work for a software company which does solutions for retail management, including inventory, POS, reporting, BI, Tags, and more. It's been in Delphi since Delphi's been around. I am actively in Stack Overflow monitoring the Delphi tag, and looking for those questions I can answer and also contributing my time to keep Stack Overflow in order. I'm not an expert in anything, a jack of all trades rather. But I love to help people when I'm able to. I've known Delphi since about 2007 now, and before that, I had learned VB6. I havn't gone back to VB since I learned Delphi. I also taught myself QBasic and HTML as a kid. It hasn't been until the past 5 years that I've been diving into programming. Since then I've also become vaguely familiar with ASP.NET with C#, as well as some C# windows apps. But I'm not too fond of the whole .NET idea. .NET is good for web platforms and such, but not for win apps. My latest work has been with Delphi 10 Seattle mobile development. I'm still very raw on the subject, but see a huge potential behind it. My strengths: Understanding the bigger picture of projects Writing Custom Classes, Components, and Controls Code organization (within unit or namespace) Writing purely independent classes (as opposed to cross-referencing units or namespaces) User Friendly UI's Developer Friendly Classes Encapsulating layers of business logic My weaknesses: Lower-level coding (such as Assembly) Platform-specific design (using Firemonkey) Web Design It's always nice to know you're able to do something, even if you never use it.

Updated on July 04, 2022

Comments

  • Jerry Dodge
    Jerry Dodge almost 2 years

    What difference does it make when I use a const parameter in a procedure?

    Take the following procedure for example:

    procedure DoSomething(Sender: TObject; const Text: String; var Reply: String);
    begin
      //Text is read-only and Reply will be passed back wherever DoSomething() was called
      Reply:= Text;
    end;
    

    The parameter Text: String is prefixed with const so that (as far as I know), a copy of the value is made and used - and is read-only. What I was wondering is how is does this affect the application any differently than if I didn't put const there? Perhaps a performance trick?

  • 500 - Internal Server Error
    500 - Internal Server Error almost 12 years
    I should add that this is true as of Delphi 2007 - the newest I have installed. I more advanced compiler could potentially detect that a parameter wasn't in fact being used as a variable even without the const prefix and not copy it, but those types of optimizations have historically not been the focus of the Delphi R&D team.
  • Stefan Glienke
    Stefan Glienke almost 12 years
    Which is the reason for this behaviour: qc.embarcadero.com/wc/qcmain.aspx?d=75036
  • Rob Kennedy
    Rob Kennedy almost 12 years
    The lack of reference-counting is the same for interfaces and strings. What you've said about interfaces isn't "in addition to" the stuff about strings. The variable gets copied all the time, but copying those is cheap since it's just copying the value of a pointer, which is sometimes no more than copying a value form one register to another.
  • Rudy Velthuis
    Rudy Velthuis almost 12 years
    It is true in all versions of Delphi that know const parameters, i.e. well before D2007: No need to copy structures, if they were passed by reference (this depends on their size), to local storage and no need to do reference counting.
  • Rudy Velthuis
    Rudy Velthuis almost 12 years
    FWIW: for how it is passed, it doesn't matter if a parameter is const or not. If it is not explicitly declared var or out, it will be passed the same for const or non-const. Generally, items larger than register size (say, 32 bit) will be passed by reference, no matter if they are const or not. The only difference between const and non-const is that for non-const, hidden code is inserted at the start that copies the item to local storage. For const, only reading references are allowed, so this copying code is missing and the passed reference is used directly.