Recent

Author Topic: FPC 3.2.2 using Result with PChar - how to ?  (Read 1148 times)

paule32

  • Sr. Member
  • ****
  • Posts: 464
  • One in all. But, not all in one.
FPC 3.2.2 using Result with PChar - how to ?
« on: April 18, 2025, 02:57:24 pm »
Hello,
currently, I doing voodoo programming ...
I have the following Code below, and I get different results for each call.
When I comment out MessageBoxA in StrCopy_ then all okay - but with message.
When I comment in MessageBoxA in StrCopy_ then I get no message Box but the result will be empty.

What is wrong there ?

Code: Pascal  [Select][+][-]
  1. function StrCopy_(var Dest: PChar; Source: PChar): PChar; stdcall; export;
  2. var
  3.   I : Integer;
  4.   L : Integer;
  5. begin
  6.   L      := StrLen(Source);
  7.  
  8.   Dest   := StrAlloc(L + 1);
  9.   result := StrAlloc(L + 1);
  10.  
  11.   i := 0;
  12.   repeat
  13.     if Source[i] = #0 then
  14.     break;
  15.     result[i] := Source[i];
  16.     Dest  [i] := Source[i];
  17.     inc(i);
  18.   until i = L;
  19.  
  20.   Dest  [L] := #0;
  21.   result[L] := #0;
  22.  
  23.   // when the below function is comment in, then
  24.   // I get empty string in StrCopy Function
  25.   // is it comment out like now, I get the same string in StrCopy as there.
  26.   MessageBoxA(0,Dest,'OPOPOPOP',0);
  27. end;
  28. function StrCopy(var Dest: PChar; Source: PChar): PChar; stdcall;
  29. var
  30.   D: PChar;
  31.   S: PChar;
  32. begin
  33.   result := StrAlloc(StrLen(Source) + 1);
  34.   StrCopy_(Dest, Source);
  35.  
  36.   // there will Dest empty, if MessageBoxA from above call is empty
  37.   MessageBoxA(0,Dest,'OPOP  OPOP',0);
  38.   result := Dest;
  39. end;
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

paule32

  • Sr. Member
  • ****
  • Posts: 464
  • One in all. But, not all in one.
[SOLVED] Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #1 on: April 18, 2025, 06:13:32 pm »
I had done it.
The FP Compiler optimize very fast and devlish good.
So, I have to explicit use the Exit(D); Function to force "touch the Result".
Else, the Result will optimzed away...
One next reason was the overlaping Result and Dest.

Code: Pascal  [Select][+][-]
  1. function StrCat_(var Dest: PChar; Source: PChar): PChar; stdcall; export;
  2. var
  3.   D       : PChar;
  4.   L, I, J : Integer;
  5. begin
  6.   L := StrLen(Dest) + StrLen(Source) + 1;
  7.   D := StrAlloc(L);
  8.  
  9.   for i := 0 to StrLen(Dest) - 1 do
  10.   D[i] := Dest[i];
  11.  
  12.   for J := 0 to StrLen(Source) - 1 do
  13.   D[i + j + 1] := Source[J];
  14.   D[i + J + 2] := #0;
  15.  
  16.   Dest := D;
  17.   Exit(D);
  18. end;
  19.  
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

jamie

  • Hero Member
  • *****
  • Posts: 6892
Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #2 on: April 18, 2025, 07:56:46 pm »
of course it seems you think that memory grows on trees.

Did you think about cleanup ?
The only true wisdom is knowing you know nothing

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1510
    • Lebeau Software
Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #3 on: April 18, 2025, 08:07:23 pm »
I have the following Code below, and I get different results for each call.

Why are you allocating dynamic memory twice?  You are leaking memory.

For that matter, a StrCopy() implementation should just copy data into an existing buffer that the caller supplies in the Dest parameter, and then return the same Dest pointer that was passed in, eg:

Code: Pascal  [Select][+][-]
  1. function StrCopy_(Dest, Source: PChar): PChar; stdcall; export;
  2. var
  3.   I, L : Integer;
  4. begin
  5.   L := StrLen(Source);  
  6.   i := 0;
  7.   repeat
  8.     if Source[i] = #0 then
  9.       break;
  10.     Dest[i] := Source[i];
  11.     Inc(i);
  12.   until i = L;
  13.  
  14.   { alternatively, and faster since StrLen() is redundant:
  15.   i := 0;
  16.   while Source[i] <> #0 do
  17.   begin
  18.     Dest[i] := Source[i];
  19.     Inc(i);
  20.   end;  
  21.   }
  22.  
  23.   Dest[i] := #0;
  24.   Result := Dest;
  25. end;
  26.  
  27. function StrCopy(Dest: PChar; Source: PChar): PChar; stdcall;
  28. begin
  29.   Result := StrCopy_(Dest, Source);
  30. end;

Code: Pascal  [Select][+][-]
  1. var buffer: array[0..10] of Char;
  2. StrCopy(buffer, 'Hello');
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

n7800

  • Sr. Member
  • ****
  • Posts: 296
Re: [SOLVED] Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #4 on: April 22, 2025, 08:26:20 pm »
Code: Pascal  [Select][+][-]
  1. function StrCat_(var Dest: PChar; Source: PChar): PChar; stdcall; export;
  2. var
  3.   D       : PChar;
  4.   L, I, J : Integer;
  5. begin
  6.   L := StrLen(Dest) + StrLen(Source) + 1;
  7.   D := StrAlloc(L);
  8.  
  9.   for i := 0 to StrLen(Dest) - 1 do
  10.   D[i] := Dest[i];
  11.  
  12.   for J := 0 to StrLen(Source) - 1 do
  13.   D[i + j + 1] := Source[J];
  14.   D[i + J + 2] := #0;
  15.  
  16.   Dest := D;
  17.   Exit(D);
  18. end;
  19.  

@paule32, note that in this code you use (on lines 13-14) the variable "i" after the loop (on lines 9-10). It's not obvious, but it's wrong, because it doesn't mean it will stay equal to the last index. See the documentation or the big thread about it.

In such cases you have to use "while" or something else.

silvercoder70

  • Full Member
  • ***
  • Posts: 186
    • Tim Coates
Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #5 on: April 23, 2025, 12:14:34 am »
If you are trying to mimic what C does then goes with what Remy says.

Even with strcat (or StrCat) the memory in the destination is expected to be large enough.
🔥 Pascal Isn’t Dead -> See What It Can Do: @silvercoder70 on YouTube

paule32

  • Sr. Member
  • ****
  • Posts: 464
  • One in all. But, not all in one.
Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #6 on: April 23, 2025, 06:46:42 am »
Thanks for yours replies.

The Point is, that I have to use "Exit(<Type>)".
Because FPC is very good in Optimize Code. And sometimes the Compiler is tending to Cut out relevant parts.
With a explicit "Exit", the Compiler is knowing a Function Call (or it thinks they have to create Code to call a Function).
That is what I have learned with FPC.
I was thinking over, that the Computer and in this case there the Compiler does what the Developer would like do - but the Counter Part is the case.
Okay, not all in the box can have the Abracadaberro Master ;-)
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5968
  • Compiler Developer
Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #7 on: April 23, 2025, 08:54:54 pm »
Because FPC is very good in Optimize Code. And sometimes the Compiler is tending to Cut out relevant parts.

If the compiler is cutting stuff that you assume to be relevant then it's more often then not a bug in your code.

With a explicit "Exit", the Compiler is knowing a Function Call (or it thinks they have to create Code to call a Function).

How did the code look like before you used Exit()?

paule32

  • Sr. Member
  • ****
  • Posts: 464
  • One in all. But, not all in one.
Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #8 on: April 23, 2025, 11:16:52 pm »
result := ...
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

Thaddy

  • Hero Member
  • *****
  • Posts: 16982
  • Ceterum censeo Trump esse delendam
Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #9 on: April 24, 2025, 08:06:26 am »
If you want have your result as a PChar, you need to allocate the correct amount of heap memory for result.
The error you make is having it only point to another value, not copy, inside the function. Every variable that is local will disappear.
That value is stack memory and will disappear on function exit: BOOOOM.
Guaranteed SIGSEV. A PChar is a pointer type, not a value type, hence the P.
« Last Edit: April 24, 2025, 10:09:25 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5968
  • Compiler Developer
Re: FPC 3.2.2 using Result with PChar - how to ?
« Reply #10 on: April 26, 2025, 03:41:53 pm »
result := ...

Assuming it's located right at the end of the function then there should be no difference between using Result and using Exit. If there is then something is really wrong with your code.

 

TinyPortal © 2005-2018