Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2010-12

constant records as default parameters

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

David Emerson

I'd like to use a constant record as a default parameter. Is there some way to do this? Here's my use case:

type
  lt_ints = record
    left, top : longint;
    end;
const
  lt_zero : lt_ints = (left:0; top:0);
procedure do_something (const offset_lt : lt_ints = lt_zero);

The procedure declaration gives an error ("illegal expression").

I assume the trouble is that lt_zero cannot be used as a default parameter value, because it is not truly a constant: it is an initialized variable.

Perhaps my real question is: how do I make a constant record which is truly constant, rather than an initialized variable?

Thoughts?

Thanks :-)
~David.

Reply by email

Howard Page-Clark
to David Emerson
David Emerson wrote 21 lines
I'd like to use a constant record as a default parameter. Is there some way to do this? Here's my use case: type lt_ints = record left, top : longint; end; const lt_zero : lt_ints = (left:0; top:0); procedure do_something (const offset_lt : lt_ints = lt_zero); The procedure declaration gives an error ("illegal expression"). I assume the trouble is that lt_zero cannot be used as a default parameter value, because it is not truly a constant: it is an initialized variable. Perhaps my real question is: how do I make a constant record which is truly constant, rather than an initialized variable?

AFAIK default parameters can only be simple types, not complex types like records. Although, I did get the following program using a default class parameter to compile and run. (And I thought you could not have var default parameters).

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
   Classes, Forms, Dialogs, StdCtrls;
type
   TForm1 = class(TForm)
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   end;
   Tduo = class
   public
     top, left: longint;
   end;
var  Form1: TForm1;
implementation
{$R *.lfm}
procedure TForm1.Button1Click(Sender: TObject);
var duo: Tduo=nil;
   procedure Doit(var du: TDuo = nil);
   begin
     if du = nil then
      begin
      du := TDuo.Create;
      du.top:=2;
      end;
   end;
begin
   Doit(duo);
   ShowMessageFmt('duo.top has value %d',[duo.top]);
   duo.Free;
end;
end.

Howard

Reply by email

David Emerson
to Howard Page-Clark
AFAIK default parameters can only be simple types, not complex types like records.

Well... it certainly appears to be so...

Although, I did get the following program using a default class parameter to compile and run.

Kinda defeats the purpose (low overhead). I'll stick with two simple params with defaults. (The other way would be to write more overloaded functions, but that's cumbersome, and has overhead of its own)

You know, it's just occurring to me that I wouldn't be saving anything anyway: any parameter with a default value must be passed-by-value, not by reference. So I'm passing two longints either way. Whether they're adjacent doesn't really make any difference at all.

(And I thought you could not have var default parameters).

You can't. Here is a much shorter example:

{$mode objfpc}
procedure s (var a : longint = 0);
  begin
    inc (a);
  end;
begin
  s;  // Error: Variable identifier expected
end.

Perhaps it's a compiler bug that it doesn't complain about the indication of a var default parameter; however it definitely complains when you actually try to put that default parameter to use. I guess the default parameter part in the function header is simply being ignored.

Thanks for your input, though! I've got a more definitive answer now.

Although I still continue to wonder about constant records and record default params, even if they can't pass-by-ref.

~David.

Reply by email