Sign in Join

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

Mailing lists / fpc-devel / 2023-01

Why: "Can't take the address of constant expressions" here?

9 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

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

Bart

Given the following program (an excerpt form a test program for a bugreport about the fpwidestring unit):

===
program test;
{$codepage utf8}
{$mode objfpc}
{$h+}
uses
  FpWideString;
var
  WSource: WideString = 'source';
  USource: UnicodeString = 'source';
  WDest: WideString = '' ;
  UDest: UnicodeString = '';
  ASource: AnsiString = 'source';
  ADest: AnsiString = '';
  P: array[0..99] of AnsiChar;

begin

  with WideStringManager do
  begin
    writeln(1);
    Wide2AnsiMoveProc(pwidechar(WSource),RawByteString(ADest),

CP_UTF8, Length(WSource));

    writeln(2);
    Ansi2WideMoveProc(PChar(ASource), CP_UTF8, UDest,

Length(ASource)); //<< test.lpr(24,53) Error: Can't take the address of constant expressions (caret behind UDest)
end.
====
C:\Users\Bart\LazarusProjecten\bugs\Console\fpwidestring>fpc test.lpr Free Pascal Compiler version 3.3.1 [2022/10/11] for i386 Copyright (c) 1993-2022 by Florian Klaempfl and others Target OS: Win32 for i386
Compiling test.lpr
test.lpr(24,53) Error: Can't take the address of constant expressions ...
UDest is of the wrong type here, it compiles fine with WDest (WideString). I just don't understand the "Can't take the address of constant expressions" I would have expected something like "Call by var for arg no. 3 has to match exactly: Got "UnicodeString" expected "WideString""

Bart

Reply by email

Michael Van Canneyt
to Bart
Bart wrote 44 lines
Given the following program (an excerpt form a test program for a bugreport about the fpwidestring unit): === program test; {$codepage utf8} {$mode objfpc} {$h+} uses FpWideString; var WSource: WideString = 'source'; USource: UnicodeString = 'source'; WDest: WideString = '' ; UDest: UnicodeString = ''; ASource: AnsiString = 'source'; ADest: AnsiString = ''; P: array[0..99] of AnsiChar; begin with WideStringManager do begin writeln(1); Wide2AnsiMoveProc(pwidechar(WSource),RawByteString(ADest), CP_UTF8, Length(WSource)); writeln(2); Ansi2WideMoveProc(PChar(ASource), CP_UTF8, UDest, Length(ASource)); //<< test.lpr(24,53) Error: Can't take the address of constant expressions (caret behind UDest) end. ==== C:\Users\Bart\LazarusProjecten\bugs\Console\fpwidestring>fpc test.lpr Free Pascal Compiler version 3.3.1 [2022/10/11] for i386 Copyright (c) 1993-2022 by Florian Klaempfl and others Target OS: Win32 for i386 Compiling test.lpr test.lpr(24,53) Error: Can't take the address of constant expressions ... UDest is of the wrong type here, it compiles fine with WDest (WideString). I just don't understand the "Can't take the address of constant expressions" I would have expected something like "Call by var for arg no. 3 has to match exactly: Got "UnicodeString" expected "WideString""

I think that what happens is that the compiler sees that it can convert widestring to unicodestring and allows a conversion, so it inserts a conversion node, but the result of the conversion is a constant expresson so it generates an error in a later stage of compilation.

But my knowledge is limited, someone else will need to confirm this.

Michael.

Reply by email

Mattias Gaertner
to Bart: Given the following program (an excerpt form a test program for a bugreport about the…
Show quoted text 32 lines
Given the following program (an excerpt form a test program for a bugreport about the fpwidestring unit): === program test; {$codepage utf8} {$mode objfpc} {$h+} uses FpWideString; var WSource: WideString = 'source'; USource: UnicodeString = 'source'; WDest: WideString = '' ; UDest: UnicodeString = ''; ASource: AnsiString = 'source'; ADest: AnsiString = ''; P: array[0..99] of AnsiChar; begin with WideStringManager do begin writeln(1); Wide2AnsiMoveProc(pwidechar(WSource),RawByteString(ADest), CP_UTF8, Length(WSource)); writeln(2); Ansi2WideMoveProc(PChar(ASource), CP_UTF8, UDest, Length(ASource)); //<< test.lpr(24,53) Error: Can't take the address of constant expressions (caret behind UDest) end.

First of all, adding a 'end;" for the "with" compiles under Linux. That's because widestring=unicodestring on Linux.

On Windows widestring is not a unicodestring and thus it can't be passed to a var parameter.

https://wiki.freepascal.org/Widestrings

Mattias

Reply by email

Sven Barth
to Bart: Given the following program (an excerpt form a test program for a bugreport about the…
Bart wrote 44 lines
Given the following program (an excerpt form a test program for a bugreport about the fpwidestring unit): === program test; {$codepage utf8} {$mode objfpc} {$h+} uses FpWideString; var WSource: WideString = 'source'; USource: UnicodeString = 'source'; WDest: WideString = '' ; UDest: UnicodeString = ''; ASource: AnsiString = 'source'; ADest: AnsiString = ''; P: array[0..99] of AnsiChar; begin with WideStringManager do begin writeln(1); Wide2AnsiMoveProc(pwidechar(WSource),RawByteString(ADest), CP_UTF8, Length(WSource)); writeln(2); Ansi2WideMoveProc(PChar(ASource), CP_UTF8, UDest, Length(ASource)); //<< test.lpr(24,53) Error: Can't take the address of constant expressions (caret behind UDest) end. ==== C:\Users\Bart\LazarusProjecten\bugs\Console\fpwidestring>fpc test.lpr Free Pascal Compiler version 3.3.1 [2022/10/11] for i386 Copyright (c) 1993-2022 by Florian Klaempfl and others Target OS: Win32 for i386 Compiling test.lpr test.lpr(24,53) Error: Can't take the address of constant expressions ... UDest is of the wrong type here, it compiles fine with WDest (WideString). I just don't understand the "Can't take the address of constant expressions" I would have expected something like "Call by var for arg no. 3 has to match exactly: Got "UnicodeString" expected "WideString""

The issue is indeed the conversion from UnicodeString to WideString which is not allowed for a var/out parameter. That the compiler doesn't use the error “Call by var for arg no. 3 has to match exactly: Got "UnicodeString" expected "WideString"” is due to Ansi2WideMoveProc() being a function pointer. The code that determines that error is not called in that case, instead the other is caused essentially as a last resort.

You can report a bug with the following sample to hopefully improve this:

=== code begin ===

program tunicode;
var
   Str: UnicodeString = 'Foobar';
procedure Test(var aArg: WideString);
begin
end;
var
   Func: procedure(var aArg: WideString) = Nil;
begin
   Test(Str);
   Func(Str);
end.

=== code end ===

Regards,
Sven

Reply by email

Bart
to Sven Barth
Show quoted text 7 lines
The issue is indeed the conversion from UnicodeString to WideString which is not allowed for a var/out parameter. That the compiler doesn't use the error “Call by var for arg no. 3 has to match exactly: Got "UnicodeString" expected "WideString"” is due to Ansi2WideMoveProc() being a function pointer. The code that determines that error is not called in that case, instead the other is caused essentially as a last resort.

Thanks for explaining.

You can report a bug with the following sample to hopefully improve this:

Reported as issue #40106

PM Sven Barth wrote 80 lines
Am 11.01.2023 um 23:58 schrieb Bart via fpc-devel: > Given the following program (an excerpt form a test program for a > bugreport about the fpwidestring unit): > > === > program test; > {$codepage utf8} > {$mode objfpc} > {$h+} > > uses > FpWideString; > > var > WSource: WideString = 'source'; > USource: UnicodeString = 'source'; > WDest: WideString = '' ; > UDest: UnicodeString = ''; > ASource: AnsiString = 'source'; > ADest: AnsiString = ''; > P: array[0..99] of AnsiChar; > > begin > with WideStringManager do > begin > writeln(1); > Wide2AnsiMoveProc(pwidechar(WSource),RawByteString(ADest), > CP_UTF8, Length(WSource)); > writeln(2); > Ansi2WideMoveProc(PChar(ASource), CP_UTF8, UDest, > Length(ASource)); //<< test.lpr(24,53) Error: Can't take the address > of constant expressions (caret behind UDest) > end. > ==== > C:\Users\Bart\LazarusProjecten\bugs\Console\fpwidestring>fpc test.lpr > Free Pascal Compiler version 3.3.1 [2022/10/11] for i386 > Copyright (c) 1993-2022 by Florian Klaempfl and others > Target OS: Win32 for i386 > Compiling test.lpr > test.lpr(24,53) Error: Can't take the address of constant expressions > ... > UDest is of the wrong type here, it compiles fine with WDest (WideString). > I just don't understand the "Can't take the address of constant expressions" > I would have expected something like "Call by var for arg no. 3 has to > match exactly: Got "UnicodeString" expected "WideString"" The issue is indeed the conversion from UnicodeString to WideString which is not allowed for a var/out parameter. That the compiler doesn't use the error “Call by var for arg no. 3 has to match exactly: Got "UnicodeString" expected "WideString"” is due to Ansi2WideMoveProc() being a function pointer. The code that determines that error is not called in that case, instead the other is caused essentially as a last resort. You can report a bug with the following sample to hopefully improve this: === code begin === program tunicode; var Str: UnicodeString = 'Foobar'; procedure Test(var aArg: WideString); begin end; var Func: procedure(var aArg: WideString) = Nil; begin Test(Str); Func(Str); end. === code end === Regards, Sven
Bart

Reply by email

Sven Barth
to Bart
Bart wrote 12 lines
> The issue is indeed the conversion from UnicodeString to WideString > which is not allowed for a var/out parameter. That the compiler doesn't > use the error “Call by var for arg no. 3 has to match exactly: Got > "UnicodeString" expected "WideString"” is due to Ansi2WideMoveProc() > being a function pointer. The code that determines that error is not > called in that case, instead the other is caused essentially as a last > resort. Thanks for explaining. > You can report a bug with the following sample to hopefully improve this: > Reported as issue #40106

Thank you.

Regards,
Sven

Reply by email

Unknown author
to Mattias Gaertner: On Wed, 11 Jan 2023 23:58:34 +0100 First of all, adding a 'end;" for the "with" compiles…
Mattias Gaertner wrote
On Wed, 11 Jan 2023 23:58:34 +0100 Bart via fpc-devel wrote:

[...]

Show quoted text 14 lines
> begin > with WideStringManager do > begin > writeln(1); > Wide2AnsiMoveProc(pwidechar(WSource),RawByteString(ADest), > CP_UTF8, Length(WSource)); > writeln(2); > Ansi2WideMoveProc(PChar(ASource), CP_UTF8, UDest, > Length(ASource)); //<< test.lpr(24,53) Error: Can't take the address > of constant expressions (caret behind UDest) > end. First of all, adding a 'end;" for the "with" compiles under Linux. That's because widestring=unicodestring on Linux.

i'm a little surprised there is no "mismatched begin/end" error with the caret pointing to the 2nd begin...

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list where it belongs!*

Reply by email

Bart
to Unknown author
AM wkitty42--- wrote 9 lines
> First of all, adding a 'end;" for the "with" compiles under Linux. > That's because widestring=unicodestring on Linux. i'm a little surprised there is no "mismatched begin/end" error with the caret pointing to the 2nd begin... --

That's a copy/paste error.by me.
The original code had about 10 more function calls and then a closing end for the "with WideStringManager do begin "

Bart

Reply by email

Unknown author
to Bart
Bart wrote 15 lines
On Fri, Jan 13, 2023 at 11:13 AM wkitty42--- via fpc-devel wrote: > >> First of all, adding a 'end;" for the "with" compiles under Linux. >> That's because widestring=unicodestring on Linux. > > i'm a little surprised there is no "mismatched begin/end" error with the caret > pointing to the 2nd begin... > > -- That's a copy/paste error.by me. The original code had about 10 more function calls and then a closing end for the "with WideStringManager do begin "

oh! that would explain it :lol:

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list where it belongs!*

Reply by email