3
votes

The following code fails to compile with [dcc32 Error] TestDefaultParameterValuePrj.dpr(13): E2026 Constant expression expected:

program TestDefaultParameterValuePrj;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

const
  SomeValue: char = 'T';

  function Test(p1: String; p2: char = SomeValue): String;
  begin
    Result := p2;
  end;

begin
  try
    Writeln(Test('Blah Blah'));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Based on this thread I could use an overloaded function if I really wanted to use the constant. However, I am surprised the compiler doesn't accept it.

1
Compiler wants true constant, yours is typed. - Free Consulting
@FreeConsulting: You are right, if I remove the type declaration it works. Post the answer and I will accept it. - costa
@costa whould your example compile with SomeValue := 'Z'; statement in the program? My bet is that you just forgot to tune compiler options and you inherited the legacy TurboPascal-cloning options set. So with those project options SomeValue is NOT a constant but a very very special kind of variables ( the semi-global one ). - Arioch 'The
@Arioch'The: Sorry, I am not sure I understand what you are saying. The code that you see was created using Delphi 10 Seattle. I selected the Console Application template to create the Delphi project. The issue was about why the compiler didn't accept a typed constant. - costa
Delphi - in all its versions - is a continuation of Turbo Pascal, as such it goes at great lengths to clone all the quirks of it, including using "const" to declare semi-global variables. Try the line I suggested. Personally I next to never compile my projects with default options. At very least I enable type safety via {$T+} :) Coming back to your example i think SomeValue is variable here, not a constant, and that is what compiler error tells us. - Arioch 'The

1 Answers

5
votes

From the documentation, with my emphasis:

You can specify default parameter values in a procedure or function heading. Default values are allowed only for typed const and value parameters. To provide a default value, end the parameter declaration with the = symbol followed by a constant expression that is assignment-compatible with the parameter's type.

A typed constant is not a constant expression. Declare your constant as a true constant which is a constant expressioin:

const
  SomeValue = 'T';

The somewhat thorny issue of true constants, typed constants and constant expressions is covered here: Declared Constants. Some key excerpts:

A constant expression is an expression that the compiler can evaluate without executing the program in which it occurs. Constant expressions include numerals; character strings; true constants; values of enumerated types; the special constants True, False, and nil; and expressions built exclusively from these elements with operators, typecasts, and set constructors.

....

This definition of a constant expression is used in several places in Delphi's syntax specification. Constant expressions are required for initializing global variables, defining subrange types, assigning ordinalities to values in enumerated types, specifying default parameter values, writing case statements, and declaring both true and typed constants.

....

Typed constants, unlike true constants, can hold values of array, record, procedural, and pointer types. Typed constants cannot occur in constant expressions.