Jump to page: 1 2
Thread overview
dChar Error
Dec 30, 2022
Salih Dincer
Dec 30, 2022
Salih Dincer
Dec 30, 2022
novice2
Dec 30, 2022
Salih Dincer
Dec 30, 2022
matheus
Dec 30, 2022
Salih Dincer
Dec 30, 2022
matheus
Dec 30, 2022
Ali Çehreli
Dec 30, 2022
matheus
Dec 31, 2022
Salih Dincer
Dec 31, 2022
Salih Dincer
Dec 31, 2022
Ali Çehreli
Dec 31, 2022
Salih Dincer
December 30, 2022

Hi All,

What is causing the error in the code snippet below?

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

December 30, 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.
December 30, 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:

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

December 30, 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:
>>
>> 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.

But a function can reference things in ROM, and a function itself can and should be held within ROM.

> 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.
December 30, 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@79

why you use .dup it example one, but not use in example two?

dchar[] str2 = cast(dchar[])"cur:€_"d.dup;

December 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:

>

 ...
 // example one:
 char[] str1 = "cur:€_".dup;
 ...
 // example two:
dchar[] str2 = cast(dchar[])"cur:€_"d;
 ...
SDB@79

why you use .dup it example one, but not use in example two?

dchar[] str2 = cast(dchar[])"cur:€_"d.dup;

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:

>

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

December 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:
>> 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@79
>>
>> why you use .dup it example one, but not use in example two?
>>
>> dchar[] str2 = cast(dchar[])"cur:€_"d.dup;
>
> 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!
> ...

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.
December 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?

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

December 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.
December 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 different

Good 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

« First   ‹ Prev
1 2