Sign in Join

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

Mailing lists / fpc-devel / 2015-02

Array of char

9 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

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

Unknown author

@ Florian.

You closed the typecast from array of char to string issue. Maybe you are right,
I just can prove that every d2-xe7 adds a #0, so a cast (partially, agreed) works in delphi and not in fpc.
I suggest you reconsider this. The raw pointer cast should work, which means an array of char should have a hidden terminator as well as a hidden pre.

With all respect,

Thaddy

Reply by email

Unknown author
to Unknown author

My bad, hidden post #0

Show quoted text 19 lines
@ Florian. You closed the typecast from array of char to string issue. Maybe you are right, I just can prove that every d2-xe7 adds a #0, so a cast (partially, agreed) works in delphi and not in fpc. I suggest you reconsider this. The raw pointer cast should work, which means an array of char should have a hidden terminator as well as a hidden pre. With all respect, Thaddy _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Jonas Maebe
to Unknown author: @ Florian. You closed the typecast from array of char to string issue. I just can prove…
@ Florian. You closed the typecast from array of char to string issue.

http://bugs.freepascal.org/view.php?id=27530

Maybe you are right, I just can prove that every d2-xe7 adds a #0, so a cast (partially, agreed) works in delphi and not in fpc.

It's unrelated to the terminating #0. It's about the hidden length and other metadata that is stored before the dynamic array and the string. This data is not compatible in either FPC or in Delphi. Delphi happens to store the length data in the same way, but other data for strings is not present with dynamic arrays (as your own test in comment 0081403 shows).

If you were to pass such typecasted arrays to arbitrary Delphi routines that expect ansistrings, you'll also get garbage results there in certain cases (because of missing code page information, so arbitrary data before the dynamic array will be interpreted as code page -- in fact, in principle this can even cause crashes, in case the memory coming before the dynamic array has not been mapped).

You'll probably also get memory corruption if you assign the result of the typecast to an ansistring, then set the dynamic array reference to nil (so the ansistring contains the last reference) and then set the ansistring to an empty string (because Delphi will then probably try to free a pointer that starts 16 or 32 bytes before the "string" data, while in case of a dynamic array it starts fewer bytes before the array data -- at least in FPC, but probably in Delphi too).

I suggest you reconsider this. The raw pointer cast should work, which means an array of char should have a hidden terminator as well as a hidden pre.

A dynamic array and an ansistring are two completely unrelated types. There is no reason why an explicit typecasts between them should work.

Jonas

Reply by email

Unknown author
to Jonas Maebe

No, it's about the K&R compatibility.
That's all, nothing more, nothing less.
It has always been there for an array of char (old c style, now ansichar) ) in Delphi.

Jonas Maebe wrote 41 lines
On 25/02/15 17:02, wrote: > @ Florian. > > You closed the typecast from array of char to string issue. http://bugs.freepascal.org/view.php?id=27530 > Maybe you are right, > I just can prove that every d2-xe7 adds a #0, so a cast (partially, > agreed) works in delphi and not in fpc. It's unrelated to the terminating #0. It's about the hidden length and other metadata that is stored before the dynamic array and the string. This data is not compatible in either FPC or in Delphi. Delphi happens to store the length data in the same way, but other data for strings is not present with dynamic arrays (as your own test in comment 0081403 shows). If you were to pass such typecasted arrays to arbitrary Delphi routines that expect ansistrings, you'll also get garbage results there in certain cases (because of missing code page information, so arbitrary data before the dynamic array will be interpreted as code page -- in fact, in principle this can even cause crashes, in case the memory coming before the dynamic array has not been mapped). You'll probably also get memory corruption if you assign the result of the typecast to an ansistring, then set the dynamic array reference to nil (so the ansistring contains the last reference) and then set the ansistring to an empty string (because Delphi will then probably try to free a pointer that starts 16 or 32 bytes before the "string" data, while in case of a dynamic array it starts fewer bytes before the array data -- at least in FPC, but probably in Delphi too). > I suggest you reconsider this. The raw pointer cast should work, which > means an array of char should have a hidden terminator as well as a > hidden pre. A dynamic array and an ansistring are two completely unrelated types. There is no reason why an explicit typecasts between them should work. Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Jonas Maebe
to Unknown author
No, it's about the K&R compatibility. That's all, nothing more, nothing less. It has always been there for an array of char (old c style, now ansichar) ) in Delphi.

A regular array of char can also be converted into a string in FPC. That's not a "raw pointer typecast" though, but an actual conversion whereby a new string "instance" is created based on the contents of the array.

Maybe we have to do that too for dynamic arrays. Can you print the value of the array pointer and the typecasted string pointer? If they are different, then that's something else and we indeed probably also have to insert a type conversion.

Jonas

Reply by email

Stefan Glienke
to Unknown author: @ Florian. You closed the typecast from array of char to string issue. I just can prove…

Maybe in D7 this works and in Delphi XE7 you also can get away with it when passing it directly to Writeln but this will throw a nice AV and the end:

program Project1;
const
   Str = 'TEST';
var
   Data: array of Char;
   s: string;
begin
   SetLength(Data, Length(Str));
   Move(Str[1], Data[0], Length(Str)*SizeOf(Char));
   s := string(Data);
end.

I debugged into the code (it's calling UStrAsg) and what it does cannot be correct because it
interprets the array of Char directly as string messing around with its refcount.

Regards
Stefan

Am 25.02.2015 um 17:02 schrieb

Show quoted text 19 lines
@ Florian. You closed the typecast from array of char to string issue. Maybe you are right, I just can prove that every d2-xe7 adds a #0, so a cast (partially, agreed) works in delphi and not in fpc. I suggest you reconsider this. The raw pointer cast should work, which means an array of char should have a hidden terminator as well as a hidden pre. With all respect, Thaddy _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Florian Klämpfl
to Jonas Maebe: A regular array of char can also be converted into a string in FPC. That's not a "raw…
Jonas Maebe wrote 15 lines
On 25/02/15 18:14, wrote: > No, it's about the K&R compatibility. > That's all, nothing more, nothing less. > It has always been there for an array of char (old c style, now > ansichar) ) in Delphi. A regular array of char can also be converted into a string in FPC. That's not a "raw pointer typecast" though, but an actual conversion whereby a new string "instance" is created based on the contents of the array. Maybe we have to do that too for dynamic arrays. Can you print the value of the array pointer and the typecasted string pointer? If they are different, then that's something else and we indeed probably also have to insert a type conversion.

This is also what I suspected but in this case the meta data would be available?

Reply by email

Jonas Maebe
to Florian Klämpfl
Florian Klämpfl wrote 12 lines
Am 25.02.2015 um 18:40 schrieb Jonas Maebe: > A regular array of char can also be converted into a string in FPC. > That's not a "raw pointer typecast" though, but an actual conversion > whereby a new string "instance" is created based on the contents of the > array. > > Maybe we have to do that too for dynamic arrays. Can you print the value > of the array pointer and the typecasted string pointer? If they are > different, then that's something else and we indeed probably also have > to insert a type conversion. This is also what I suspected but in this case the meta data would be available?

Yes, but just very maybe the "0" code page was from CP_ACP. Although afaik Delphi always substitutes the actual value of DefaultSystemCodePage in instantiated strings, so that's probably not the case.

Jonas

Reply by email

Florian Klämpfl
to Jonas Maebe
Jonas Maebe wrote 18 lines
On 25/02/15 18:50, Florian Klämpfl wrote: > Am 25.02.2015 um 18:40 schrieb Jonas Maebe: >> A regular array of char can also be converted into a string in FPC. >> That's not a "raw pointer typecast" though, but an actual conversion >> whereby a new string "instance" is created based on the contents of the >> array. >> >> Maybe we have to do that too for dynamic arrays. Can you print the value >> of the array pointer and the typecasted string pointer? If they are >> different, then that's something else and we indeed probably also have >> to insert a type conversion. > > This is also what I suspected but in this case the meta data would be available? Yes, but just very maybe the "0" code page was from CP_ACP. Although afaik Delphi always substitutes the actual value of DefaultSystemCodePage in instantiated strings, so that's probably not the case.

That's why I asked to print the result of StringElementSize :)

Reply by email