Author Topic: var vs out (including "const" related aspects)  (Read 3095 times)

Paolo

  • Hero Member
  • *****
  • Posts: 787
var vs out (including "const" related aspects)
« on: August 11, 2026, 10:24:43 am »
Hello,

usually I have procedure with this format

Code: Pascal  [Select][+][-]
  1. procedure DoSomething(var Inp1, Inp2.. ; var Out1, Out2..);
  2.  

In the procedure declaration the parameters are always sorted with the inputs first and the outputs last.
Typically, the output vars are uninitialized being their purpose to be set by the procedure itself.
However, this generates a lot of warning about uninitialized var.
To overcame this, it seems very easy to change the “var” with “out” in the procedure declaration, making also more evident the intentions and avoiding the warning.

Code: Pascal  [Select][+][-]
  1. procedure DoSomething(var Inp1, Inp2.. ; out Out1, Out2..);
  2.  

Are there counterindications (side effects) on this approach? is this the recommended one?

Regards.

PS: here the editor does not recognize out as reserved word and it is not shown in bold !
« Last Edit: August 12, 2026, 04:46:23 pm by Paolo »

creaothceann

  • Sr. Member
  • ****
  • Posts: 448
Re: var vs out
« Reply #1 on: August 11, 2026, 11:08:55 am »
Afaik there are no downsides.

Note that parameters only used as inputs but marked as var parameters can also accidentally modify the variables at the call site, so it'd be better to use const for those parameters.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12995
  • FPC developer.
Re: var vs out
« Reply #2 on: August 11, 2026, 11:30:13 am »
Afaik there are no downsides.

Don't pass a variable to OUT that you also pass in some other way (Parameter aliassing). Specially with managed type, the initialisation situation of the out parameter might not be what you expect.

I don't use OUT much, so I don't remember the exact reasons.

Paolo

  • Hero Member
  • *****
  • Posts: 787
Re: var vs out
« Reply #3 on: August 11, 2026, 11:49:45 am »
thanks both for the replay..

@marcov : are you referring to situation like:

Code: Pascal  [Select][+][-]
  1. procedure DoSomething(var Inp1: type1; out Out1: Type1);
  2.  
  3. ..
  4.   DoSomething(A, A);
  5. ..
  6.  
« Last Edit: August 11, 2026, 12:00:22 pm by Paolo »

creaothceann

  • Sr. Member
  • ****
  • Posts: 448
Re: var vs out
« Reply #4 on: August 11, 2026, 12:13:27 pm »
If I understand it correctly: you could have e.g. 2 AnsiString variables (which are special pointers) that point to the same string in memory, and passing both via reference and changing them could have strange effects.

Paolo

  • Hero Member
  • *****
  • Posts: 787
Re: var vs out
« Reply #5 on: August 11, 2026, 12:22:51 pm »
Ah.. thanks again.

Concerning usage of const instead of var, it implies that the compiler block code with assignment to it, but the parameter is still passed as reference, right ?

thanks.

creaothceann

  • Sr. Member
  • ****
  • Posts: 448
Re: var vs out
« Reply #6 on: August 11, 2026, 12:46:08 pm »
Quote
Contrary to Delphi, no assumptions should be made about how const parameters are passed to the underlying routine. In particular, the assumption that parameters with large size are passed by reference is not correct. For this the constref parameter type should be used
- https://www.freepascal.org/docs-html/ref/refsu67.html

LemonParty

  • Hero Member
  • *****
  • Posts: 654
Re: var vs out
« Reply #7 on: August 11, 2026, 01:17:26 pm »
Quote
Contrary to Delphi, no assumptions should be made about how const parameters are passed to the underlying routine. In particular, the assumption that parameters with large size are passed by reference is not correct. For this the constref parameter type should be used
- https://www.freepascal.org/docs-html/ref/refsu67.html
This thing could case a serious bugs. I met with it when tryied to pass to function an array of elements by passing reference to the first element like this:
Code: Pascal  [Select][+][-]
  1. function Func(const Buf: Byte; Count: SizeUInt): Integer;
  2. var
  3.   eBuf: array [Byte] of Byte absolute Buf;
  4. begin
  5.   WriteLn(eBuf[1]);{can't access this element because const copy only one byte}
  6. end;
This solve by using constref instead of const.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

Paolo

  • Hero Member
  • *****
  • Posts: 787
Re: var vs out
« Reply #8 on: August 11, 2026, 01:23:32 pm »
knowing in which way the parameters are passed it is an important aspect !
statement like "..no assumption.." calls for avoiding using const key word at all.

Dankan1890

  • New Member
  • *
  • Posts: 18
Re: var vs out
« Reply #9 on: August 11, 2026, 03:07:15 pm »
This thing could case a serious bugs. I met with it when tryied to pass to function an array of elements by passing reference to the first element like this:
Code: Pascal  [Select][+][-]
  1. function Func(const Buf: Byte; Count: SizeUInt): Integer;
  2. var
  3.   eBuf: array [Byte] of Byte absolute Buf;
  4. begin
  5.   WriteLn(eBuf[1]);{can't access this element because const copy only one byte}
  6. end;
This solve by using constref instead of const.
Maybe I'm wrong, but you're overlaying a 256-byte array on a single byte, so only the first one is correct (eBuf[0]), but the rest (eBuf[1..255]) are "random" memory locations.

For elementary types, const usually passes values, not references.

Obviously, I'll defer to more experienced users; I haven't programmed in decades, and I only discovered FPC three months ago.

LemonParty

  • Hero Member
  • *****
  • Posts: 654
Re: var vs out
« Reply #10 on: August 11, 2026, 04:01:40 pm »
Dankan1890, that is a trick how you can pass an array into function. It useful when you have many overloads like:
Code: Pascal  [Select][+][-]
  1. function Func(constref Arr: Byte; Count: SizeUInt): Integer;
  2. function Func(constref Arr: ShortInt; Count: SizeUInt): Integer;
  3. function Func(constref Arr: Word; Count: SizeUInt): Integer;
  4. function Func(constref Arr: SmallInt; Count: SizeUInt): Integer;
  5. {...}
This is useful because then you can write:
Code: Pascal  [Select][+][-]
  1. Func(Arr[0], 42);
and depending of type of Arr the correct function will be called. You may even change the type of Arr and the code will keep doing the correct operation (of course you need to implement all needed overloads).
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

Dankan1890

  • New Member
  • *
  • Posts: 18
Re: var vs out
« Reply #11 on: August 11, 2026, 05:14:07 pm »
@LemonParty: with constref it is correct, as you force the passing of a constant reference, my "reasoning" was on the initial code with only const and why it did not work as expected.

Paolo

  • Hero Member
  • *****
  • Posts: 787
Re: var vs out
« Reply #12 on: August 11, 2026, 05:58:16 pm »
Constref seems more reliable and forces passing parametrs by reference.
« Last Edit: August 11, 2026, 06:25:15 pm by Paolo »

Thausand

  • Hero Member
  • *****
  • Posts: 613
Re: var vs out
« Reply #13 on: August 11, 2026, 06:17:50 pm »
make use dynarray or pointer for type
Code: Pascal  [Select][+][-]
  1. function Func(Arr: TByteDynArray; Count: SizeUInt): Integer;
  2. function Func(Arr: PByte; Count: SizeUInt): Integer;
  3.  
A docile goblin always follow HERMES.md

Dankan1890

  • New Member
  • *
  • Posts: 18
Re: var vs out
« Reply #14 on: August 11, 2026, 06:34:09 pm »
@Paolo: going back to the topic (var vs out), the difference is explained here https://www.freepascal.org/docs-html/ref/refsu66.html.

 

TinyPortal © 2005-2018