Re: [fpc-pascal] Difference between string and Tbytes as procedure arguments?

2023-11-05 Thread Michael Van Canneyt via fpc-pascal




On Sun, 5 Nov 2023, Bo Berglund via fpc-pascal wrote:



You must copy the data. The copy() function can be used for this.


Follow-up question:

Can I change the function declaration like this and preserve the content?

function TSSConnection.ParseCmdFileData(var SSCmdFile: TSSCommandFile; const
Buf:  TBytes): boolean;


This does not preserve the content. The "const" means you cannot change the
pointer, so

Buf:=a;

will fail

But

Buf[0]:=1;

will still compile.



Or must I copy the argument Buf inside the function to a local BufL version?
That is what you adviced, right?


Yes.

Mcihael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Creating capturers

2023-11-05 Thread Sven Barth via fpc-pascal
Hairy Pixels  schrieb am Sa., 4. Nov. 2023, 15:48:

>
>
> > On Nov 4, 2023, at 4:22 PM, Sven Barth 
> wrote:
> >
> > Then don't assign them every "frame". If you just keep them around then
> they aren't more expensive than a virtual method call.
> > And any other mechanism would involve the heap as well, because that's
> how anonymous functions that capture variables work and thus anything that
> wants to store them must play by the same rules. There won't be any changes
> there.
> >
>
> The need for a universal function pointer type really isn't about the
> function references even though they work for that, albeit with unneeded
> overhead.
>
> Lets say you have a sort function which takes a compare callback
> parameter. You can make the callback type "is nested" which works on global
> and nested/anonymous functions but not methods. What if the user wants to
> provide the compare function as a method because they're calling it in a
> class which shares the code elsewhere? As the writer of the function you'd
> need to make 2 versions of the function, one "is nested" and "of object".
>
> The writer of the sort function shouldn't need to know what kind of
> function it will be passed, just that a comparison callback is provided,
> right?
>

Then you simply make the callback function type a function reference and be
done. The user can pass in any kind of function they want and *nearly*
every type of function-like pointer.

And if you're really worried about performance when providing such a class
then simply provide overloads woth different function-like pointer types,
the compiler will pick the most suitable one then.

It's really not that hard as an implementer of a class.

Regards,
Sven

>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Compiler probem?

2023-11-05 Thread Sven Barth via fpc-pascal
Paul Renaud via fpc-pascal  schrieb am
Sa., 4. Nov. 2023, 16:18:

> Hi, I have a question about some code.
>
> The following code segment generated a compiler error when I compiled it
> with...
>
> fpc Sample -Se -gl -al
>
> but not when it's compiled with...
>
> fpc Sample -Se -gl
>
> ...
> Asm
>   LdRH R0, [ R1, R2, LSL #1 ]
> End [ 'R0',  'R1' ];
> ...
>
> Any idea why?  Its driving me crazy.
>

Please provide information what target your compiling for, what target you
are compiling from, the compiler version you are using, the exact error you
get and a complete code example.

Regards,
Sven

>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Difference between string and Tbytes as procedure arguments?

2023-11-05 Thread Bo Berglund via fpc-pascal
On Sun, 5 Nov 2023 10:36:47 +0100 (CET), Michael Van Canneyt via fpc-pascal
 wrote:

>> So my question is this:
>> Is there a difference in handling the arguments between string, AnsiString,
>> RawByteString and TBytes in a declaration like this:
>>
>> function TSSConnection.ParseCmdFileData(var SSCmdFile: TSSCommandFile; Buf:
>> AnsiString): boolean;
>>
>> and this:
>>
>> function TSSConnection.ParseCmdFileData(var SSCmdFile: TSSCommandFile; Buf:
>> TBytes): boolean;
>>
>> In the first instance it looks like the function receives a *copy* of the 
>> data
>
>No, but an ansistring is copy-on-write. As soon as you change it, a copy is
>made if your routine is not the only one using the string.
>
>> in the Buf argument and in the second case it receives a pointer to the 
>> actual
>> live data such that in the first case the argument source remains untouched
>> whereas in the second case the argument source is changed just as it had been
>> declared as var...
>
>That is correct. TBytes is a fancy wrapper around a pointer with some
>reference counting added to the mix.
>
>>
>> Is there a way to simply tell Delphi/FreePascal to treat also TBytes as copy
>> rather than a pointer to the real data?
>
>You must copy the data. The copy() function can be used for this.

Follow-up question:

Can I change the function declaration like this and preserve the content?

function TSSConnection.ParseCmdFileData(var SSCmdFile: TSSCommandFile; const
Buf:  TBytes): boolean;

Or must I copy the argument Buf inside the function to a local BufL version?
That is what you adviced, right?

Note: I have now found another function that changes the content of the Buf
argument and it too causes havoc...


-- 
Bo Berglund
Developer in Sweden

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Compiler probem?

2023-11-05 Thread Adriaan van Os via fpc-pascal

Paul Renaud via fpc-pascal wrote:

Hi, I have a question about some code.

The following code segment generated a compiler error when I compiled it 
with...


"A compiler error" assumes that we all have a crystal ball to look in 

Regards,

Adriaan van Os

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Difference between string and Tbytes as procedure arguments?

2023-11-05 Thread Bo Berglund via fpc-pascal
I am maintaining an old utility program that started out about 20+ years ago
using Delphi7.

The utility communicates via RS232 with a measuring system in order to retrieve
and process recorded data and at the time this was started I used strings as
buffers for the serial comm.

A string at the time was really just an array of 1-byte characters but it had
useful functions for manipulating data inside so it made sense to use strings at
the time.

But as time evolved and Borland changed the meaning of string to now be
unicodestring it could no longer be used as a comm buffer, so I switched
declaration to AnsiString or even RawByteString to keep the existing utility
tools operational.

New programs I wrote would use TBytes as buffer instead...

Then about 6-7 years ago I had to do a major overhaul of the program in order to
improve the user interface and add support for switching languages in the UI and
at that time I also tried my best to replace the AnsiString buffers with TBytes
buffers. At this time I was on Delphi XE5.

It all looked OK until I recently got a call from a distributor who had
discovered that for a certain type of seldom used data collection mode the
output was corrupted when transfered to disk

And now I have found that the corruption happens inside a function that analyzes
one of the data packets where it will remove the start header record from the
buffer and then continue parsing the data items. (The buffer is sent in as a
regular argument without the var specifier).

Following this analysis in main code the buffer itself (that was used in the
previous call) is saved to disk in binary format.
And here is the problem:

The saved image of the buffer lacks the header part (30 bytes)...

So my question is this:
Is there a difference in handling the arguments between string, AnsiString,
RawByteString and TBytes in a declaration like this:

function TSSConnection.ParseCmdFileData(var SSCmdFile: TSSCommandFile; Buf:
AnsiString): boolean;

and this:

function TSSConnection.ParseCmdFileData(var SSCmdFile: TSSCommandFile; Buf:
TBytes): boolean;

In the first instance it looks like the function receives a *copy* of the data
in the Buf argument and in the second case it receives a pointer to the actual
live data such that in the first case the argument source remains untouched
whereas in the second case the argument source is changed just as it had been
declared as var...

Is there a way to simply tell Delphi/FreePascal to treat also TBytes as copy
rather than a pointer to the real data?


-- 
Bo Berglund
Developer in Sweden

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Difference between string and Tbytes as procedure arguments?

2023-11-05 Thread Michael Van Canneyt via fpc-pascal




On Sun, 5 Nov 2023, Bo Berglund via fpc-pascal wrote:


I am maintaining an old utility program that started out about 20+ years ago
using Delphi7.

The utility communicates via RS232 with a measuring system in order to retrieve
and process recorded data and at the time this was started I used strings as
buffers for the serial comm.

A string at the time was really just an array of 1-byte characters but it had
useful functions for manipulating data inside so it made sense to use strings at
the time.

But as time evolved and Borland changed the meaning of string to now be
unicodestring it could no longer be used as a comm buffer, so I switched
declaration to AnsiString or even RawByteString to keep the existing utility
tools operational.

New programs I wrote would use TBytes as buffer instead...

Then about 6-7 years ago I had to do a major overhaul of the program in order to
improve the user interface and add support for switching languages in the UI and
at that time I also tried my best to replace the AnsiString buffers with TBytes
buffers. At this time I was on Delphi XE5.

It all looked OK until I recently got a call from a distributor who had
discovered that for a certain type of seldom used data collection mode the
output was corrupted when transfered to disk

And now I have found that the corruption happens inside a function that analyzes
one of the data packets where it will remove the start header record from the
buffer and then continue parsing the data items. (The buffer is sent in as a
regular argument without the var specifier).

Following this analysis in main code the buffer itself (that was used in the
previous call) is saved to disk in binary format.
And here is the problem:

The saved image of the buffer lacks the header part (30 bytes)...

So my question is this:
Is there a difference in handling the arguments between string, AnsiString,
RawByteString and TBytes in a declaration like this:

function TSSConnection.ParseCmdFileData(var SSCmdFile: TSSCommandFile; Buf:
AnsiString): boolean;

and this:

function TSSConnection.ParseCmdFileData(var SSCmdFile: TSSCommandFile; Buf:
TBytes): boolean;

In the first instance it looks like the function receives a *copy* of the data


No, but an ansistring is copy-on-write. As soon as you change it, a copy is
made if your routine is not the only one using the string.


in the Buf argument and in the second case it receives a pointer to the actual
live data such that in the first case the argument source remains untouched
whereas in the second case the argument source is changed just as it had been
declared as var...


That is correct. TBytes is a fancy wrapper around a pointer with some
reference counting added to the mix.



Is there a way to simply tell Delphi/FreePascal to treat also TBytes as copy
rather than a pointer to the real data?


You must copy the data. The copy() function can be used for this.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal