digitalmars.D.learn - dChar Error
- Salih Dincer (38/38) Dec 29 2022 Hi All,
- Richard (Rikki) Andrew Cattermole (3/3) Dec 29 2022 Because, string literals are in Read Only Memory (or should be anyway).
- Salih Dincer (27/30) Dec 29 2022 There is no such thing as a ROM within a function. Because str
- Richard (Rikki) Andrew Cattermole (8/19) Dec 29 2022 But a function can reference things in ROM, and a function itself can
- novice2 (3/11) Dec 30 2022 why you use .dup it example one, but not use in example two?
- Salih Dincer (8/21) Dec 30 2022 If I do not use .dup in the 1st example and convert as
- matheus (21/40) Dec 30 2022 Are you sure about that?
- Salih Dincer (17/18) Dec 30 2022 Thank you for your answer. You contributed to the project I was
- matheus (35/49) Dec 30 2022 Unfortunately I can't say because I'm not a skilled D programmer,
- =?UTF-8?Q?Ali_=c3=87ehreli?= (7/11) Dec 30 2022 In this case it does copy but in the case of dchar[] to dchar[], there
- matheus (5/11) Dec 30 2022 Very interesting I did some testing and you are right. So better
- Salih Dincer (42/47) Dec 30 2022 I have one more little question! Is it possible to infer the
- Salih Dincer (42/43) Dec 30 2022 Let me save you the torment of code duplication 😀
- =?UTF-8?Q?Ali_=c3=87ehreli?= (32/34) Dec 30 2022 Since the bodies of all three overloads are the same except some types,
- Salih Dincer (53/57) Dec 30 2022 You took the trouble, thanks, but there is a special reason why I
Hi All, What is causing the error in the code snippet below? ```d void replaceRight(S)(ref S[] str, S[] slc) {  size_t len1 = slc.length,     len2 = str[len1..$].length;  assert(len1 == len2);  str[len1..$] = slc; } import std.stdio; void main() {  // example one:  char[] str1 = "cur:€_".dup;  str1.length.write(": "); // 8:  str1[4..$].writefln!"[%s]"; // [€_]   str1.replaceRight("$ _".dup);  str1.writefln!"[%s]"; // [cur:$  _]  // example two: dchar[] str2 = cast(dchar[])"cur:€_"d;  str2.length.write(": "); // 6:  str2[4..$].writefln!"[%s]"; // [€_]   str2.replaceRight(cast(dchar[])"$ _"d);  str2.writefln!"[%s]"; // Error--^ } /* Prints:  8: [€_]  [cur:$ _]  6: [€_] Error: program killed by signal 11 */ ``` Why does replaceRight() work fine with a char array, but not a dchar array? Whereas, rvalue and lvalue lengths are equal to each other! SDB 79
Dec 29 2022
Because, string literals are in Read Only Memory (or should be anyway). If you write to ROM, it'll of course error by the CPU. So when you duplicated it, it was no longer in ROM, and therefore writable.
Dec 29 2022
On Friday, 30 December 2022 at 04:54:39 UTC, Richard (Rikki) Andrew Cattermole wrote:So when you duplicated it, it was no longer in ROM, and therefore writable.There is no such thing as a ROM within a function. Because str is a reference and slc is a local copy, right? Have you tried running the code? Okay, no string literals: ```d void main() {  // example one:  char[] str1 = "cur:€_".dup;  str1.length.write(": "); // 8:  str1[4..$].writefln!"[%s]"; // [€_]    char[] slc1 = "$ _".dup;  str1.replaceRight(slc1);  str1.writefln!"[%s]"; // [cur:$  _]  // example two: dchar[] str2 = cast(dchar[])"cur:€_"d;  str2.length.write(": "); // 6:  str2[4..$].writefln!"[%s]"; // [€_]   dchar[] slc2 = cast(dchar[])"$ _"d;  str2.replaceRight(slc2);  str2.writefln!"[%s]"; } ``` SDB 79
Dec 29 2022
On 30/12/2022 6:37 PM, Salih Dincer wrote:On Friday, 30 December 2022 at 04:54:39 UTC, Richard (Rikki) Andrew Cattermole wrote:But a function can reference things in ROM, and a function itself can and should be held within ROM.So when you duplicated it, it was no longer in ROM, and therefore writable.There is no such thing as a ROM within a function.Because str is a reference and slc is a local copy, right?It is a reference to memory that is in ROM. No, it is not a copy of the memory, only of the reference. You shouldn't be casting away immutable btw, (which is what string is!).Have you tried running the code? Okay, no string literals:Of course; I cannot see anything else that could cause this in the assembly either.
Dec 29 2022
On Friday, 30 December 2022 at 04:43:48 UTC, Salih Dincer wrote: ...  // example one:  char[] str1 = "cur:€_".dup;  ...  // example two: dchar[] str2 = cast(dchar[])"cur:€_"d;  ... SDB 79why you use .dup it example one, but not use in example two? dchar[] str2 = cast(dchar[])"cur:€_"d.dup;
Dec 30 2022
On Friday, 30 December 2022 at 09:29:16 UTC, novice2 wrote:On Friday, 30 December 2022 at 04:43:48 UTC, Salih Dincer wrote:If I do not use .dup in the 1st example and convert as cast(char[]), it gives an error. However, in the 2nd example using .dup does nothing. It's not working anyway! On Friday, 30 December 2022 at 05:46:32 UTC, Richard (Rikki) Andrew Cattermole wrote: ...  // example one:  char[] str1 = "cur:€_".dup;  ...  // example two: dchar[] str2 = cast(dchar[])"cur:€_"d;  ... SDB 79why you use .dup it example one, but not use in example two? dchar[] str2 = cast(dchar[])"cur:€_"d.dup;Of course; I cannot see anything else that could cause this in the assembly either.I'm not sure I understand this issue. SDB 79
Dec 30 2022
On Friday, 30 December 2022 at 10:03:20 UTC, Salih Dincer wrote:On Friday, 30 December 2022 at 09:29:16 UTC, novice2 wrote:Are you sure about that? Because replacing this: dchar[] str2 = cast(dchar[])"cur:€_"d; with this: dchar[] str2 = (cast(dchar[])"cur:€_").dup; Worked for me: 8: [€_] [cur:$ _] 6: [€_] [cur$ _] A small example of the problem: import std.stdio; void main(){ dchar[] str1 = (cast(dchar[])"cur:€_").dup; dchar[] str2 = (cast(dchar[])"cur:€_"); str1[0] = '1'; //str2[0] = '1'; // this will give: Error: program killed by signal 11 } Matheus.On Friday, 30 December 2022 at 04:43:48 UTC, Salih Dincer wrote:If I do not use .dup in the 1st example and convert as cast(char[]), it gives an error. However, in the 2nd example using .dup does nothing. It's not working anyway! ... ...  // example one:  char[] str1 = "cur:€_".dup;  ...  // example two: dchar[] str2 = cast(dchar[])"cur:€_"d;  ... SDB 79why you use .dup it example one, but not use in example two? dchar[] str2 = cast(dchar[])"cur:€_"d.dup;
Dec 30 2022
On Friday, 30 December 2022 at 11:05:07 UTC, matheus wrote:Are you sure about that?Thank you for your answer. You contributed to the project I was working on. In this case, std.conv.to can be used for mutable dchars, right? For example, is this solution the right approach? ```d auto toDchar(S)(inout S str) { import std.conv : to; return str.to!(dchar[]); } void main() { auto str3 = "ÜÇ ON "d; auto str4 = "BİR İKİ BEŞ "d.dup; auto str5 = "DÖRT ALTI YEDİ ".toDchar; //str5.fun(5); } ``` SDB 79
Dec 30 2022
On Friday, 30 December 2022 at 15:28:05 UTC, Salih Dincer wrote:... In this case, std.conv.to can be used for mutable dchars, right? For example, is this solution the right approach? ```d auto toDchar(S)(inout S str) { import std.conv : to; return str.to!(dchar[]); } void main() { auto str3 = "ÜÇ ON "d; auto str4 = "BİR İKİ BEŞ "d.dup; auto str5 = "DÖRT ALTI YEDİ ".toDchar; //str5.fun(5); } ```Unfortunately I can't say because I'm not a skilled D programmer, I use mostly as a C on steroids. But yes I think it will generate a copy (mutable) based on this test: void main(){ import std.stdio; import std.conv; auto str1 = "BİR İKİ BEŞ "; auto str2 = str1; auto str3 = str2.to!(dchar[]); writeln(str1, ", ", str1.ptr); writeln(str2, ", ", str2.ptr); writeln(str3, ", ", str3.ptr); str3[0] = 'A'; writeln(str3, ", ", str3.ptr); } It prints: BİR İKİ BEŞ , 5641226D8200 BİR İKİ BEŞ , 5641226D8200 BİR İKİ BEŞ , 7FB466EAE000 AİR İKİ BEŞ , 7FB466EAE000 So for str2 = str1 it is just a case of passing the reference, and both are pointing to the same address, while in the case of: "str3 = str2.to!(dchar[]);", the address is different, and accepts changing its content (str3[0] = 'A'). In the docs: https://dlang.org/phobos/std_conv.html#to "String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable)." But I couldn't find if the target will be mutable, but I think it will be, unless explicitly otherwise with a cast I believe. Anyway I would wait and see if someone more skilled could shed a light. Matheus.
Dec 30 2022
On 12/30/22 13:54, matheus wrote:But yes I think it will generate a copy (mutable) based on this test:In this case it does copy but in the case of dchar[] to dchar[], there will be no copy. Similarly, there is no copy from immutable to immutable.the address is differentGood test. :)But I couldn't find if the target will be mutable, but I think it will be,The target will always be the type the programmer specifies explicitly. (dchar[] in this case.) Ali
Dec 30 2022
On Friday, 30 December 2022 at 22:02:41 UTC, Ali Çehreli wrote:On 12/30/22 13:54, matheus wrote:Very interesting I did some testing and you are right. So better to stick with .dup! Thanks for the info, Matheus.But yes I think it will generate a copy (mutable) based onthis test: In this case it does copy but in the case of dchar[] to dchar[], there will be no copy. Similarly, there is no copy from immutable to immutable.
Dec 30 2022
On Friday, 30 December 2022 at 22:02:41 UTC, Ali Çehreli wrote:I have one more little question! Is it possible to infer the string without the type the programmer specifies explicitly in the template below? ```d template Fun(dstring str)/* template Fun(T)(T str)/* like this */ { import std.traits : Unconst;  alias T = Unconst!(typeof(str[0]));  auto Fun() { import std.conv : to; auto result = Result();   result.data = str.to!(T[]);   return result;  }  struct Result { union { T[str.length] data; ubyte[T.sizeof * str.length] bytes; } string toString() { import std.format; return format("%s: %(%02X-%)", data, bytes); } } } void main() {  import std.stdio : writeln;  Fun!"β€Ş"w.writeln; // type1: wstring  Fun!"β€Ş"d.writeln; // type2: dstring } ``` That is, the compiler can/must infer between type 1-2 or type 3(string) that it knows at compile time, right? SDB 79But I couldn't find if the target will be mutable, but Ithink it willbe,The target will always be the type the programmer specifies explicitly. (dchar[] in this case.)
Dec 30 2022
On Saturday, 31 December 2022 at 00:42:50 UTC, Salih Dincer wrote:... it possible to inferLet me save you the torment of code duplication 😀 Thanks everyone. Yes, I guess there is no other way but to overload. This is both the safest and the fastest. It's also short enough like this: ```d // D 2.0.83 or higher import std.stdio : writeln; import std.conv : to; auto Fun(string str)() { auto result = Values!(char, str.length)(); result.data = str.to!(char[]); return result; } auto Fun(wstring str)() { auto result = Values!(wchar, str.length)(); result.data = str.to!(wchar[]); return result; } auto Fun(dstring str)() { auto result = Values!(dchar, str.length)(); result.data = str.to!(dchar[]); return result; } struct Values(T, size_t len) { union { T[len] data; ubyte[T.sizeof * len] bytes; } string toString() { import std.format; return format("%s: %(%02X-%)", data, bytes); } } void main() { Fun!"β€Ş".writeln; // β€Ş: CE-B2-E2-82-AC-C5-9E Fun!"β€Ş"w.writeln; // β€Ş: B2-03-AC-20-5E-01 Fun!"β€Ş"d.writeln; // B2-03-00-00-AC-20-00-00-5E-01-00-00 } ``` SDB 79
Dec 30 2022
On 12/30/22 17:22, Salih Dincer wrote:I guess there is no other way but to overload.Since the bodies of all three overloads are the same except some types, they can easily be templatized.This is both the safest and the fastest.I didn't think Values is fast with string copies that it makes. ;) I think it was only for showing the byte values but you can do the same by casting to ubyte[] as well. Also, your Fun could work only with string literals; so I used function parameters. import std.traits : isSomeString; // isSomeString may or may not be useful below. (?) auto Fun(S)(S str) if (isSomeString!S) { import std.traits : Unqual; import std.conv : to; alias T = Unqual!S; // Note: The following may or may not copy the string // depending on whether S is the same as T. return str.to!T; } void printBytes(S)(S str) { import std.stdio : writefln; import std.conv : to; // The following cast does not copy anything. writefln!"%(%02X-%)"(cast(ubyte[])str); } void main() { printBytes(Fun("β€Ş")); // CE-B2-E2-82-AC-C5-9E printBytes(Fun("β€Ş"w)); // B2-03-AC-20-5E-01 printBytes(Fun("β€Ş"d)); // B2-03-00-00-AC-20-00-00-5E-01-00-00 } Ali
Dec 30 2022
On Saturday, 31 December 2022 at 02:15:56 UTC, Ali Çehreli wrote:On 12/30/22 17:22, Salih Dincer wrote:You took the trouble, thanks, but there is a special reason why I use union. If we want, we can write dynamic version without using std.traits: ```d struct Values(T, size_t len = 1) { union { T[len] data; ubyte[T.sizeof * len] bytes; } string toString() { import std.format; return format("%s: %(%02X-%)", data, bytes); } } alias Char = Values!char; alias Wchar = Values!wchar; alias Dchar = Values!dchar; void main() { import std.stdio : writeln; Char[] str1; str1 ~= Char('B'); str1 ~= Char('E'); str1 ~= Char('$'); str1.writeln; Wchar[] str2; str2 ~= Wchar('β'); str2 ~= Wchar('€'); str2 ~= Wchar('Ş'); str2.writeln; Dchar[] str3; str3 ~= Dchar('β'); str3 ~= Dchar('€'); str3 ~= Dchar('$'); str3.writeln("\n"); Fun!"β€$".writeln; } /* [B: 42, E: 45, $: 24] [β: B2-03, €: AC-20, Ş: 5E-01] [β: B2-03-00-00, €: AC-20-00-00, $: 24-00-00-00] β€$: CE-B2-E2-82-AC-24 */ ``` However, I would like to draw your attention to the last line. Yeah, I won't be able to do that because it's New Year's Eve. But the line is like mixed mode because of the non-char data it contains, right? Happy New Year...I guess there is no other way but to overload.Since the bodies of all three overloads are the same except some types, they can easily be templatized.
Dec 30 2022