-3

When i defined typed constant can't use it in default value of functions argument, for example:

const
  DEFC   :Char  = ',';

  function fun(delimiter :char=DEFC);

When run this code compiler show this error :

[dcc32 Error] : E2026 Constant expression expected

if not defined this type, compiler set type to AnsiChar and this is bad for my code, How can i use this way or a way which can say compiler to use Char and not use AnsiChar for character constants?

MohsenB
  • 1,669
  • 18
  • 29

2 Answers2

1

You seem to rely a little bit too much on tool-tip information. That info is not produced by the actual compiler, and is not worth to place bets on.

Anyway, character and string literals are context sensitive. That means that the compiler (actual code generator) will create appropriate code depending on how the literal is used.

Consider these two consts (as alternatives):

const
  DEFC = ',';     // tool-tip shows System.AnsiChar
  DEFC = #$0298;  // tool-tip shows System.AnsiChar here too!

This just shows that the tool-tip can't be relied on here, because it doesn't know in what context the const will be used.

Then consider the following two functions:

function fun1(delimiter: Char = DEFC): integer;
begin
  result := ord(delimiter);
end;

function fun2(delimiter: AnsiChar = DEFC): integer;
begin
  result := ord(delimiter);
end;

and the following OnClick handler, calling those functions

procedure TMainForm.Button7Click(Sender: TObject);
begin
  ShowMessage(inttostr(fun1));
  ShowMessage(inttostr(fun2));
end;

The code produced by the compiler differs for the two calls

MainFormU.pas.233: ShowMessage(inttostr(fun1));
00605036 66B89802         mov ax,$0298   // $002c if DEFC = ','
0060503A E8A5FFFFFF       call fun1
...
MainFormU.pas.234: ShowMessage(inttostr(fun2));
0060504F B098             mov al,$98     // $2c if DEFC = ','
00605051 E8A6FFFFFF       call fun2
...

In the first call, to fun1() which requires a Char, the DEFC literal is treated as a Unicode char, #$2098 (or $002c if DEFC = ',').

In the second call, to fun2() which requires an AnsiChar, the DEFC const is treated as an AnsiChar, #$98 (or $2c if DEFC = ',').

IOW, the character literal is context sensitive, as stated above.

As a side note, it is worrying that no compiler warning was issued for the second call.

Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
0

when you add a datatype to your const it is no longer a const but a variable, and that what the compiler is telling you. Remove the type form your const and it compiles.

Like this:

const
  DEFC = ',';

function fun(delimiter: Char = DEFC) : Integer;
begin

end;
Jens Borrisholt
  • 6,174
  • 1
  • 33
  • 67
  • I explained that in this case compiler set type to `AnsiChar` and I do not want it, i want type of constant is `Char`. – MohsenB Oct 10 '15 at 08:43
  • I cant figure out what the real problem is. Look at this code: const DEFC = ','; function fun(delimiter: Char = DEFC): Integer; begin end; procedure TForm33.FormCreate(Sender: TObject); var MyChar: Char; begin fun(); MyChar:= ';'; fun(myChar); end; In both cases, the parameter is transferes via the AX register. – Jens Borrisholt Oct 10 '15 at 09:18
  • you can see the type in tool-tip when writing code in editor. – MohsenB Oct 10 '15 at 09:46
  • I don't care about tool tip. Asserbmler is the real world. In the assembler code are the same for both examples. – Jens Borrisholt Oct 10 '15 at 14:21