Lazarus

Free Pascal => General => Topic started by: cryborg2 on July 10, 2020, 03:06:11 pm

Title: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: cryborg2 on July 10, 2020, 03:06:11 pm
With Delphi

  asm
    //...
    CALL  System.@LStrSetLength
    //...
  end;

It works.


With FP/Lazarus

// asm mode: intel

  asm
    //...
    CALL  @fpc_ansistr_setlength
    //...
  end;

it should work, but actually not, it gives: "Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH"

I have no clue about what's going on at this moment. Any help will be appreciated.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: PascalDragon on July 10, 2020, 04:32:27 pm
With FP/Lazarus

// asm mode: intel

  asm
    //...
    CALL  @fpc_ansistr_setlength
    //...
  end;

it should work, but actually not, it gives: "Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH"

I have no clue about what's going on at this moment. Any help will be appreciated.

You need to reimport the procedure and then call that:

Code: Pascal  [Select][+][-]
  1. Procedure fpc_AnsiStr_SetLength (Var S : RawByteString; l : SizeInt{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING});external 'FPC_ANSISTR_SETLENGTH';
  2.  
  3. procedure Test;
  4. begin
  5.   asm
  6.     call fpc_ansistr_setlength
  7.   end;
  8. end;
  9.  
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: Jonas Maebe on July 10, 2020, 06:09:33 pm
I would strongly recommend against doing that. This is a routine that is only accessible by the compiler itself by design. There are no guarantees regarding its signature or behaviour in detail, definitely not across versions. If you want this, define your own procedure that in turn calls setlength. It will be slightly slower, but setlength itself generally does so much work that it probably won't be noticeable.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: cryborg2 on July 11, 2020, 08:48:05 am
With FP/Lazarus

// asm mode: intel

  asm
    //...
    CALL  @fpc_ansistr_setlength
    //...
  end;

it should work, but actually not, it gives: "Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH"

I have no clue about what's going on at this moment. Any help will be appreciated.

You need to reimport the procedure and then call that:

Code: Pascal  [Select][+][-]
  1. Procedure fpc_AnsiStr_SetLength (Var S : RawByteString; l : SizeInt{$ifdef FPC_HAS_CPSTRING}; cp : TSystemCodePage{$endif FPC_HAS_CPSTRING});external 'FPC_ANSISTR_SETLENGTH';
  2.  
  3. procedure Test;
  4. begin
  5.   asm
  6.     call fpc_ansistr_setlength
  7.   end;
  8. end;
  9.  

I have tried it as you mentioned (with a slight modification as I still using the good old FP 2.6.4):
procedure fpc_AnsiStr_SetLength (Var S: AnsiString; l: SizeInt{$ifdef FPC_HAS_CPSTRING};cp: TSystemCodePage{$endif FPC_HAS_CPSTRING}); external 'FPC_ANSISTR_SETLENGTH';

It says: FPC_ANSISTR_SETLENGTH.dll not found.

Then I changed the DLL name to 'TEST.EXE', an gave it another try: The application was unable to start correctly (0xc000007b).

Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: PascalDragon on July 11, 2020, 11:08:52 am
I have tried it as you mentioned (with a slight modification as I still using the good old FP 2.6.4):
procedure fpc_AnsiStr_SetLength (Var S: AnsiString; l: SizeInt{$ifdef FPC_HAS_CPSTRING};cp: TSystemCodePage{$endif FPC_HAS_CPSTRING}); external 'FPC_ANSISTR_SETLENGTH';

Ah, sorry, I meant external name 'FPC_ANSISTR_SETLENGTH'.

But I'd head Jonas' advice as well: write your own function that calls SetLength.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: cryborg2 on July 11, 2020, 12:07:35 pm
I have tried it as you mentioned (with a slight modification as I still using the good old FP 2.6.4):
procedure fpc_AnsiStr_SetLength (Var S: AnsiString; l: SizeInt{$ifdef FPC_HAS_CPSTRING};cp: TSystemCodePage{$endif FPC_HAS_CPSTRING}); external 'FPC_ANSISTR_SETLENGTH';

Ah, sorry, I meant external name 'FPC_ANSISTR_SETLENGTH'.

But I'd head Jonas' advice as well: write your own function that calls SetLength.

Oh, it working, thank you! ;)
I am not planning to use any new version of FPC, because 3.0.4 generated code is erratic, so I think I can kindly ignore the latter advices.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: PascalDragon on July 11, 2020, 02:47:55 pm
I am not planning to use any new version of FPC, because 3.0.4 generated code is erratic, so I think I can kindly ignore the latter advices.

In how far is it erratic? Do you have an example? If we don't know about it, we can't fix it. Though you could also test whether 3.2 solves it.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: cryborg2 on July 11, 2020, 03:30:59 pm
I am not planning to use any new version of FPC, because 3.0.4 generated code is erratic, so I think I can kindly ignore the latter advices.

In how far is it erratic? Do you have an example? If we don't know about it, we can't fix it. Though you could also test whether 3.2 solves it.

No, I have failed to make any example. I has only the whole code in which the error appears repeatedly at the same exact point.
I have managed to find its location, but was unable to reproduce it within a test example program.
I cannot put together a report in the absence of an example. So I gave up.
I used to report every new issues I encountered, and I used to solve them myself and send my patches or suggestions of solution.
But it was an exception.  :(
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: PascalDragon on July 11, 2020, 05:36:27 pm
You say that you managed to locate it. Is it wrongly generated assembly code? Does it occur only on specific platforms? Does it only occur with specific optimization settings? Is the function inlined? Are generics involved? Did the problems also occur with 3.0.2 or 3.0.0?

Maybe indeed do a test with 3.2, many things were fixed in the code generator and parser. You could maybe also do a test with 3.3.1.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: cryborg2 on July 16, 2020, 12:18:00 am
You say that you managed to locate it. Is it wrongly generated assembly code? Does it occur only on specific platforms? Does it only occur with specific optimization settings? Is the function inlined? Are generics involved? Did the problems also occur with 3.0.2 or 3.0.0?

Maybe indeed do a test with 3.2, many things were fixed in the code generator and parser. You could maybe also do a test with 3.3.1.

Sigh.. I cannot promise anything.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: cryborg2 on July 26, 2020, 08:03:20 am
You say that you managed to locate it. Is it wrongly generated assembly code? Does it occur only on specific platforms? Does it only occur with specific optimization settings? Is the function inlined? Are generics involved? Did the problems also occur with 3.0.2 or 3.0.0?

Maybe indeed do a test with 3.2, many things were fixed in the code generator and parser. You could maybe also do a test with 3.3.1.

Now I did it! An error always there with fpc version >= 3.0.0
I'm not sure if it causes one error or more.

But I have succesfully pluck my original code to create an example to reproduce one. All we need is a Button, and the Dialogs unit:


function GetScriptResult: Boolean;
  var s: string;
begin
  s:='('+#176+')';
  Result:=Copy(s, 2, 1)=#176;
end;

procedure TForm1.ButtonClick_CalculateAll(Sender: TObject);
begin
  if GetScriptResult then
    ShowMessage('Ok, it works!')
  else
    ShowMessage('ERROR, OUCH!');
end;

My program uses byte code in strings as commands, and this just breaks it.  %)
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: Aidex on July 26, 2020, 09:27:43 am
#176 is not a valid UTF8 character.
You should try RawByteString instead of String!

In your example, s[2] (a single character) could give a different result than Copy(s,2,1) (an Utf8 string).

You can't compare an incorrectly encoded string to a correctly encoded UTF8 string constant.
The character #176 as UTF8-string is not that single character #176, but its UTF8 encoded representation! Therefore the comparison fails.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: cryborg2 on July 27, 2020, 12:56:10 am
#176 is not a valid UTF8 character.
You should try RawByteString instead of String!

In your example, s[2] (a single character) could give a different result than Copy(s,2,1) (an Utf8 string).

You can't compare an incorrectly encoded string to a correctly encoded UTF8 string constant.
The character #176 as UTF8-string is not that single character #176, but its UTF8 encoded representation! Therefore the comparison fails.

 >:( Who talking about UTF8? Who expecting UTF8? Everythig worked perfectly with fpc 2.6.4. It's not supposed to handle it that way. If so, then they changed it arbitrarily. Originally, I used this charceter/string constant '°' (AltGr + 5), and {$codepage cp437} was set at the top of the Pascal unit with the same result. With 2.6.4 it was OK, from 3.0.0 it wasn't.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: PascalDragon on July 27, 2020, 09:19:22 am
There is nothing arbitrary about this. The code page aware AnsiString type was the big feature (and change) in FPC 3.0.0 (see here (https://wiki.freepascal.org/User_Changes_3.0#AnsiStrings_are_now_codepage-aware) which also references this (https://wiki.freepascal.org/FPC_Unicode_support)). The FPC RTL itself initializes with the code page of the operating system, but Lazarus forces this to be UTF-8 (see here (https://wiki.freepascal.org/Unicode_Support_in_Lazarus)), thus why you don't have any problem with a command line application, but see this issue with a LCL GUI application.

To better explain where your problem is:

Code: Pascal  [Select][+][-]
  1. s:='('+#176+')';
  2. Result:=Copy(s, 2, 1)=#176;

The string constant at the right side of the assignment to s is in your system's code page. Due to the LCL's setting of using UTF-8 by default the assignment will convert the string to UTF-8 (you can see this by using Length(s), it will return a value > 3). Thus the following Copy will extract only a part of the UTF-8 character for #176, thus the comparison will fail.
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: cryborg2 on July 28, 2020, 08:29:25 am
There is nothing arbitrary about this. The code page aware AnsiString type was the big feature (and change) in FPC 3.0.0 (see here (https://wiki.freepascal.org/User_Changes_3.0#AnsiStrings_are_now_codepage-aware) which also references this (https://wiki.freepascal.org/FPC_Unicode_support)). The FPC RTL itself initializes with the code page of the operating system, but Lazarus forces this to be UTF-8 (see here (https://wiki.freepascal.org/Unicode_Support_in_Lazarus)), thus why you don't have any problem with a command line application, but see this issue with a LCL GUI application.

To better explain where your problem is:

Code: Pascal  [Select][+][-]
  1. s:='('+#176+')';
  2. Result:=Copy(s, 2, 1)=#176;

The string constant at the right side of the assignment to s is in your system's code page. Due to the LCL's setting of using UTF-8 by default the assignment will convert the string to UTF-8 (you can see this by using Length(s), it will return a value > 3). Thus the following Copy will extract only a part of the UTF-8 character for #176, thus the comparison will fail.

When implementing a new feature, it should be introduced as an extra option beside the well-known old one, not by replacing it!
I still don't understand, why they blatantly REPLACING something with a totally different incompatible thing, messing up existing codes.  :o
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: PascalDragon on July 28, 2020, 09:08:49 am
There is nothing arbitrary about this. The code page aware AnsiString type was the big feature (and change) in FPC 3.0.0 (see here (https://wiki.freepascal.org/User_Changes_3.0#AnsiStrings_are_now_codepage-aware) which also references this (https://wiki.freepascal.org/FPC_Unicode_support)). The FPC RTL itself initializes with the code page of the operating system, but Lazarus forces this to be UTF-8 (see here (https://wiki.freepascal.org/Unicode_Support_in_Lazarus)), thus why you don't have any problem with a command line application, but see this issue with a LCL GUI application.

To better explain where your problem is:

Code: Pascal  [Select][+][-]
  1. s:='('+#176+')';
  2. Result:=Copy(s, 2, 1)=#176;

The string constant at the right side of the assignment to s is in your system's code page. Due to the LCL's setting of using UTF-8 by default the assignment will convert the string to UTF-8 (you can see this by using Length(s), it will return a value > 3). Thus the following Copy will extract only a part of the UTF-8 character for #176, thus the comparison will fail.

When implementing a new feature, it should be introduced as an extra option beside the well-known old one, not by replacing it!
I still don't understand, why they blatantly REPLACING something with a totally different incompatible thing, messing up existing codes.  :o

There was no way to implement this optionally. The code page aware string is a base part of the language and the way the LCL simply stuffed UTF-8 characters into AnsiStrings was simply wrong now due to the compiler now automatically inserting conversions between code pages thus leading to corruption of the string data.
Also even if we had made this optional, the new behaviour would have been the default anyway and would you have found out that you'd need to change some hypothetical switch? Considering that you didn't know about the string related changes I assume you would not have. So what use would it have been anyway?
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: winni on July 28, 2020, 10:43:45 am

When implementing a new feature, it should be introduced as an extra option beside the well-known old one, not by replacing it!
I still don't understand, why they blatantly REPLACING something with a totally different incompatible thing, messing up existing codes.  :o

Wellcome to the new millenium!
Wellcome to Unicode!

Both are now 20 years old. Unicode even older!

Toto - we are not at DOS anymore!

Winni
Title: Re: Error: Unknown label identifier @FPC_ANSISTR_SETLENGTH
Post by: tetrastes on July 28, 2020, 12:13:58 pm
There was no way to implement this optionally. The code page aware string is a base part of the language and the way the LCL simply stuffed UTF-8 characters into AnsiStrings was simply wrong now due to the compiler now automatically inserting conversions between code pages thus leading to corruption of the string data.
Also even if we had made this optional, the new behaviour would have been the default anyway and would you have found out that you'd need to change some hypothetical switch? Considering that you didn't know about the string related changes I assume you would not have. So what use would it have been anyway?

Moreover, there is such switch: https://wiki.freepascal.org/Lazarus_with_FPC3.0_without_UTF-8_mode .
TinyPortal © 2005-2018