Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster wrote: When I run the program and close the window, the program still runs in background mode. I don't know why this happens nor how to fix it. Does anybody know what's going on? frame beat me to it, but it may well be that you're getting -1. [The documentation][1] says that a window that has already been destroyed will result in the `hWnd` parameter being invalid, which will cause the function to return -1. [1]: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage#return-value
Re: Any UML generators for D code?
On 13/08/2021 9:40 AM, russhy wrote: also this but it's pretty old: https://github.com/rikkimax/Duml It was a neat idea duml of mine, but I wouldn't recommend going down the path of CTFE for this. Best to write a tool using dmd-fe instead.
Re: Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.
On Friday, 13 August 2021 at 00:30:59 UTC, Ruby The Roobster wrote: When I run the program and close the window, the program still runs in background mode. I don't know why this happens nor how to fix it. Does anybody know what's going on? AFAIK GetMessage() may return -1 if some error happend, so your loop won't exit.
Help with Win32: PostQuitMessage(0) doesn't post WM_QUIT apparently, because the message loop is not exited.
Here is the message loop: ```d while(GetMessage(&msg, hwnd,0,0)) { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } ``` The WndProc(LRESULT CALLBACK): ```d extern(Windows) LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) nothrow { switch(msg) { case WM_CREATE: //... return 0; break; case WM_DESTROY: try { entity.terminate(); } catch(Throwable e) { PostQuitMessage(1); } PostQuitMessage(0); break; default: } return DefWindowProc(hwnd,msg,wparam,lparam); } ``` When I run the program and close the window, the program still runs in background mode. I don't know why this happens nor how to fix it. Does anybody know what's going on?
Re: Any UML generators for D code?
On Thursday, 12 August 2021 at 21:11:24 UTC, JN wrote: I'd like to see the relationships between my D classes in a graphical form. Is there any tool that supports that? found this: https://code.dlang.org/packages/depend also this but it's pretty old: https://github.com/rikkimax/Duml
Any UML generators for D code?
I'd like to see the relationships between my D classes in a graphical form. Is there any tool that supports that?
Re: Unnable to join Discord
On Thursday, 12 August 2021 at 18:11:20 UTC, nayy wrote: Hi I cannot seems to be able to join the discord server It gives me the following error: "unable to accept invit" Is the invitation link expired? https://dlang.org/community.html https://discord.gg/bMZk9Q4 I joined last week with the same link. It worked. Try updating your app, maybe?
Unnable to join Discord
Hi I cannot seems to be able to join the discord server It gives me the following error: "unable to accept invit" Is the invitation link expired? https://dlang.org/community.html https://discord.gg/bMZk9Q4
Re: Cannot catch exception in debug mode
On Thursday, 12 August 2021 at 03:46:00 UTC, kinke wrote: @frame: Please file an issue. https://issues.dlang.org/show_bug.cgi?id=22205
Re: I do not understand copy constructors
On 8/12/21 4:32 AM, Paul Backus wrote: > Qualifying the ctor as `inout` works fine I can see how a DConf Online presention is shaping up in your head. ;) http://dconf.org/2021/online/index.html We need a collective understanding of effective use of such fundamental concepts. Ali
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 16:12:39 UTC, Paul Backus wrote: On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote: [...] You have forgotten to add a member variable of type `A` to your `B` struct. If you add one, you will see the following error message: [...] "implicit conversions are not allowed for arguments passed to `ref` parameters" was the point missing to me. Good to know, and thank yo to everyone!
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote: It is not clear to me why the inout generated copy constructor of the B structure is not able to copy the A structure. struct A { int[] data; this(ref return scope A rhs){ /* body */ } this(ref return scope const A rhs) const { /* body */} this(ref return scope immutable A rhs) immutable { /* body */} } struct B { // default generated copy constructor, by section 14.15.6.2 this(ref return scope inout(B) src) inout { foreach (i, ref inout field; src.tupleof) this.tupleof[i] = field; } } Can point me to a code example of when the D generated copy constructor fails to copy A, and why? You have forgotten to add a member variable of type `A` to your `B` struct. If you add one, you will see the following error message: ``` onlineapp.d(18): Error: none of the overloads of `__ctor` are callable using a `inout` object, candidates are: onlineapp.d(5):`onlineapp.A.this(return ref scope A rhs)` onlineapp.d(6):`onlineapp.A.this(return ref scope const(A) rhs)` onlineapp.d(7):`onlineapp.A.this(return ref scope immutable(A) rhs)` ``` (Full example: https://run.dlang.io/is/9BrpZj) Essentially, you cannot use a mutable, `const`, or `immutable` copy constructor to copy an `inout` object, only an `inout` copy constructor. The reason for this is a bit subtle. Normally, `inout` can convert to `const`, so you might expect that the `const` copy constructor could be used to construct a copy of an `inout` object. However, copy constructors take their arguments by `ref`, and implicit conversions are not allowed for arguments passed to `ref` parameters. (I cannot find a citation in the spec for this, but you can verify it yourself.) Here's a simplified example that gives the same error: ```d void f(inout(int)[] a) { g(a); } void g(ref int[] a) {} void g(ref const(int)[] a) {} void g(ref immutable(int)[] a) {} ```
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 15:50:05 UTC, Tejas wrote: On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote: On Thursday, 12 August 2021 at 14:57:16 UTC, Steven Schveighoffer wrote: [...] It is not clear to me why the inout generated copy constructor of the B structure is not able to copy the A structure. [...] Why will copy constructor of ```struct B``` accept argument of type ```A```? You are right, I forgot the A member, now it is clear: struct A { int[] data; this(ref return scope A rhs){} this(ref return scope const A rhs) const {} this(ref return scope immutable A rhs) immutable {} } struct B { // default generated copy constructor, by section 14.15.6.2 this(ref return scope inout(B) src) inout { foreach (i, ref inout field; src.tupleof) this.tupleof[i] = field; } A a; } Error: none of the overloads of `__ctor` are callable using a `inout` object, candidates are: `A.this(return ref scope A rhs)` `A.this(return ref scope const(A) rhs)` `A.this(return ref scope immutable(A) rhs)` Thank you everybody.
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 15:39:40 UTC, Learner wrote: On Thursday, 12 August 2021 at 14:57:16 UTC, Steven Schveighoffer wrote: [...] It is not clear to me why the inout generated copy constructor of the B structure is not able to copy the A structure. [...] Why will copy constructor of ```struct B``` accept argument of type ```A```?
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 14:57:16 UTC, Steven Schveighoffer wrote: On 8/12/21 10:08 AM, Learner wrote: On Thursday, 12 August 2021 at 13:56:17 UTC, Paul Backus wrote: On Thursday, 12 August 2021 at 12:10:49 UTC, Learner wrote: That worked fine, but the codebase is @safe: ```d cast from `int[]` to `inout(int[])` not allowed in safe code ``` So copy constructors force me to introduce trusted methods, while that was not necessary with postblits? A postblit would simply ignore the type qualifier--which can lead to undefined behavior. (Scroll down to the paragraph that begins "An unqualified postblit..." under ["Struct Postblits"][1] in the spec.) The copy constructor merely forces you to be honest about the safety of your code. In your case, I would recommend encapsulating the unsafe cast in a function like the following: ```d T[] dupWithQualifiers(T[] array) { auto copy = array.dup; return (() @trusted => cast(T[]) copy)(); } ``` You can then use this function in place of `dup` in your copy constructor. [1]: https://dlang.org/spec/struct.html#struct-postblit Thank you, now everything is more clear. A last question, if you do not mind, just to better understand inout. It seems a shortcut to avoid repeating the same function body for mutable, const, and immutable. Why the following code is not equal to the single inout constructor? struct A { int[] data; //this(ref return scope inout A rhs) inout { /*body*/ } this(ref return scope Timestamp rhs) { /*body*/ } this(ref return scope const Timestamp rhs) const { /*body*/ } this(ref return scope immutable Timestamp rhs) immutable { /*body*/ } } Error: Generating an `inout` copy constructor for `struct B` failed, therefore instances of it are uncopyable Inout is compatible only with inout, and not with the unrolled code it implies? inout is not like a template. It's a separate qualifier that generates only one function (not 3 unrolled ones). It's sort of viral like const is viral -- all underlying pieces have to support inout in order for you to write inout functions. -Steve It is not clear to me why the inout generated copy constructor of the B structure is not able to copy the A structure. struct A { int[] data; this(ref return scope A rhs){ /* body */ } this(ref return scope const A rhs) const { /* body */} this(ref return scope immutable A rhs) immutable { /* body */} } struct B { // default generated copy constructor, by section 14.15.6.2 this(ref return scope inout(B) src) inout { foreach (i, ref inout field; src.tupleof) this.tupleof[i] = field; } } Can point me to a code example of when the D generated copy constructor fails to copy A, and why?
Re: I do not understand copy constructors
On 8/12/21 10:08 AM, Learner wrote: On Thursday, 12 August 2021 at 13:56:17 UTC, Paul Backus wrote: On Thursday, 12 August 2021 at 12:10:49 UTC, Learner wrote: That worked fine, but the codebase is @safe: ```d cast from `int[]` to `inout(int[])` not allowed in safe code ``` So copy constructors force me to introduce trusted methods, while that was not necessary with postblits? A postblit would simply ignore the type qualifier--which can lead to undefined behavior. (Scroll down to the paragraph that begins "An unqualified postblit..." under ["Struct Postblits"][1] in the spec.) The copy constructor merely forces you to be honest about the safety of your code. In your case, I would recommend encapsulating the unsafe cast in a function like the following: ```d T[] dupWithQualifiers(T[] array) { auto copy = array.dup; return (() @trusted => cast(T[]) copy)(); } ``` You can then use this function in place of `dup` in your copy constructor. [1]: https://dlang.org/spec/struct.html#struct-postblit Thank you, now everything is more clear. A last question, if you do not mind, just to better understand inout. It seems a shortcut to avoid repeating the same function body for mutable, const, and immutable. Why the following code is not equal to the single inout constructor? struct A { int[] data; //this(ref return scope inout A rhs) inout { /*body*/ } this(ref return scope Timestamp rhs) { /*body*/ } this(ref return scope const Timestamp rhs) const { /*body*/ } this(ref return scope immutable Timestamp rhs) immutable { /*body*/ } } Error: Generating an `inout` copy constructor for `struct B` failed, therefore instances of it are uncopyable Inout is compatible only with inout, and not with the unrolled code it implies? inout is not like a template. It's a separate qualifier that generates only one function (not 3 unrolled ones). It's sort of viral like const is viral -- all underlying pieces have to support inout in order for you to write inout functions. -Steve
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 13:56:17 UTC, Paul Backus wrote: On Thursday, 12 August 2021 at 12:10:49 UTC, Learner wrote: That worked fine, but the codebase is @safe: ```d cast from `int[]` to `inout(int[])` not allowed in safe code ``` So copy constructors force me to introduce trusted methods, while that was not necessary with postblits? A postblit would simply ignore the type qualifier--which can lead to undefined behavior. (Scroll down to the paragraph that begins "An unqualified postblit..." under ["Struct Postblits"][1] in the spec.) The copy constructor merely forces you to be honest about the safety of your code. In your case, I would recommend encapsulating the unsafe cast in a function like the following: ```d T[] dupWithQualifiers(T[] array) { auto copy = array.dup; return (() @trusted => cast(T[]) copy)(); } ``` You can then use this function in place of `dup` in your copy constructor. [1]: https://dlang.org/spec/struct.html#struct-postblit Thank you, now everything is more clear. A last question, if you do not mind, just to better understand inout. It seems a shortcut to avoid repeating the same function body for mutable, const, and immutable. Why the following code is not equal to the single inout constructor? struct A { int[] data; //this(ref return scope inout A rhs) inout { /*body*/ } this(ref return scope Timestamp rhs) { /*body*/ } this(ref return scope const Timestamp rhs) const { /*body*/ } this(ref return scope immutable Timestamp rhs) immutable { /*body*/ } } Error: Generating an `inout` copy constructor for `struct B` failed, therefore instances of it are uncopyable Inout is compatible only with inout, and not with the unrolled code it implies?
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 12:10:49 UTC, Learner wrote: That worked fine, but the codebase is @safe: ```d cast from `int[]` to `inout(int[])` not allowed in safe code ``` So copy constructors force me to introduce trusted methods, while that was not necessary with postblits? A postblit would simply ignore the type qualifier--which can lead to undefined behavior. (Scroll down to the paragraph that begins "An unqualified postblit..." under ["Struct Postblits"][1] in the spec.) The copy constructor merely forces you to be honest about the safety of your code. In your case, I would recommend encapsulating the unsafe cast in a function like the following: ```d T[] dupWithQualifiers(T[] array) { auto copy = array.dup; return (() @trusted => cast(T[]) copy)(); } ``` You can then use this function in place of `dup` in your copy constructor. [1]: https://dlang.org/spec/struct.html#struct-postblit
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 12:28:32 UTC, Learner wrote: On Thursday, 12 August 2021 at 12:22:22 UTC, Tejas wrote: On Thursday, 12 August 2021 at 12:19:56 UTC, Tejas wrote: [...] Works with ```@safe``` as well Paul was just trying to make that other answer work, you don't have to make copy constructors ```@trusted``` Operations are needed on `other` data, that was the reason for a `postblit` in the original case: an `int[]` data array needs to be duplicated. Hey, this should be good enough now: ```d import std; struct Foo { this(ref inout Foo other) /*inout*/ @safe{ /*foreach(i, v; other.tupleof) this.tupleof[i] = cast(typeof(this.tupleof[i]))v;*/ a = other.a; b = other.b; foreach(i, elem ;other.c) c[i] = elem; } @disable this(this); int a; float b; double[] c; } void main()@safe{ immutable Foo a; const Foo c; Foo b = a;//mutable b from immutable a //writeln(typeof(b).stringof); //Output is Foo const Foo d = c;//const d from const c Foo e = c;//mutable e from const c //immutable Foo f = b;//immutable f from mutable b I don't know why this fails but const from mutable succeeds const Foo g = b;//const g from mutable b } ```
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 12:22:22 UTC, Tejas wrote: On Thursday, 12 August 2021 at 12:19:56 UTC, Tejas wrote: [...] Works with ```@safe``` as well Paul was just trying to make that other answer work, you don't have to make copy constructors ```@trusted``` Ignore this, it doesn't work for dynamic arrays(but it does for static, ie, fixed length arrays)
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 12:22:22 UTC, Tejas wrote: On Thursday, 12 August 2021 at 12:19:56 UTC, Tejas wrote: [...] Works with ```@safe``` as well Paul was just trying to make that other answer work, you don't have to make copy constructors ```@trusted``` Operations are needed on `other` data, that was the reason for a `postblit` in the original case: an `int[]` data array needs to be duplicated.
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 12:19:56 UTC, Tejas wrote: On Thursday, 12 August 2021 at 11:54:22 UTC, Learner wrote: [...] Just add ```inout``` inside ```this(ref inout/*notice the inout*/ Foo other) inout/*notice the inout*/``` Example code: ```d struct Foo { this(ref inout Foo other) inout { foreach(i, v; other.tupleof) this.tupleof[i] = v; } @disable this(this); int a; float b; double c; } void main(){ immutable Foo a; const Foo c; Foo b = a;//mutable b and immutable a const Foo d = c;//const d and const c Foo e = c;//mutable e and const c immutable Foo f = b;//immutable f and mutable b const Foo g = b;//const g and mutable b } ``` Works with ```@safe``` as well Paul was just trying to make that other answer work, you don't have to make copy constructors ```@trusted```
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 11:54:22 UTC, Learner wrote: On Thursday, 12 August 2021 at 10:10:17 UTC, rikki cattermole wrote: On 12/08/2021 9:36 PM, Learner wrote: It seems that there is no easy way to transition from a postblit to a copy constructor, no? struct Foo { this(ref Foo other) { foreach(i, v; other.tupleof) this.tupleof[i] = v; } @disable this(this); } This results to: Generating an `inout` copy constructor for `struct A` failed, therefore instances of it are uncopyable Just add ```inout``` inside ```this(ref inout/*notice the inout*/ Foo other) inout/*notice the inout*/``` Example code: ```d struct Foo { this(ref inout Foo other) inout { foreach(i, v; other.tupleof) this.tupleof[i] = v; } @disable this(this); int a; float b; double c; } void main(){ immutable Foo a; const Foo c; Foo b = a;//mutable b and immutable a const Foo d = c;//const d and const c Foo e = c;//mutable e and const c immutable Foo f = b;//immutable f and mutable b const Foo g = b;//const g and mutable b } ```
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 11:32:03 UTC, Paul Backus wrote: On Thursday, 12 August 2021 at 11:19:34 UTC, drug wrote: ```D struct A { int[] data; this(ref return scope inout A rhs) /* no inout here */ { data = rhs.data.dup; } } ``` The problem is that if you qualify the ctor itself then if you pass const/immutable rhs to it then the ctor is const/immutable too (like the args) and of course you cannot modify this, so the error. To make a copy ctor you need to qualify copy ctor args as inout but the copy ctor itself shall be mutable and have no const,immutable or inout qualifier. This is not true. Qualifying the ctor as `inout` works fine: https://run.dlang.io/is/Kpzp5M The problem in this example is that `.dup` always returns a mutable array, even if the array being copied is `inout`. The solution is to cast the copy back to the original type: ```d this(ref return scope inout A rhs) inout { data = cast(typeof(rhs.data)) rhs.data.dup; } ``` That worked fine, but the codebase is @safe: ```d cast from `int[]` to `inout(int[])` not allowed in safe code ``` So copy constructors force me to introduce trusted methods, while that was not necessary with postblits?
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 11:07:24 UTC, drug wrote: 12.08.2021 12:36, Learner пишет: > It seems that there is no easy way to transition from a postblit to a copy constructor, no? You just need both const and mutable copy ctors to replace inout one: ```D struct A { int[] data; this(ref return scope A rhs) { data = rhs.data.dup; } this(ref return scope const A rhs) const { data = rhs.data.dup; } } ``` the mutable copy ctor accepts mutable data and the const copy ctor accepts const and immutable data That still fails: Generating an `inout` copy constructor for `struct B` failed, therefore instances of it are uncopyable Also if I remove the `const` body (can I assign data if the method is const?) ```D struct A { int[] data; this(ref return scope A rhs) { data = rhs.data.dup; } this(ref return scope const A rhs) const {} } Generating an `inout` copy constructor for `struct B` failed, therefore instances of it are uncopyable ```
Re: I do not understand copy constructors
12.08.2021 14:32, Paul Backus пишет: This is not true. Qualifying the ctor as `inout` works fine: https://run.dlang.io/is/Kpzp5M The problem in this example is that `.dup` always returns a mutable array, even if the array being copied is `inout`. The solution is to cast the copy back to the original type: ```d this(ref return scope inout A rhs) inout { data = cast(typeof(rhs.data)) rhs.data.dup; } ``` Yes, it's not true. I forgot that ctors are special in contrast to regular methods and can modify the aggregate they belong to even if the ctor has const/immutable/inout qualifier.
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 10:10:17 UTC, rikki cattermole wrote: On 12/08/2021 9:36 PM, Learner wrote: It seems that there is no easy way to transition from a postblit to a copy constructor, no? struct Foo { this(ref Foo other) { foreach(i, v; other.tupleof) this.tupleof[i] = v; } @disable this(this); } This results to: Generating an `inout` copy constructor for `struct A` failed, therefore instances of it are uncopyable
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 11:19:34 UTC, drug wrote: ```D struct A { int[] data; this(ref return scope inout A rhs) /* no inout here */ { data = rhs.data.dup; } } ``` The problem is that if you qualify the ctor itself then if you pass const/immutable rhs to it then the ctor is const/immutable too (like the args) and of course you cannot modify this, so the error. To make a copy ctor you need to qualify copy ctor args as inout but the copy ctor itself shall be mutable and have no const,immutable or inout qualifier. This is not true. Qualifying the ctor as `inout` works fine: https://run.dlang.io/is/Kpzp5M The problem in this example is that `.dup` always returns a mutable array, even if the array being copied is `inout`. The solution is to cast the copy back to the original type: ```d this(ref return scope inout A rhs) inout { data = cast(typeof(rhs.data)) rhs.data.dup; } ```
Re: I do not understand copy constructors
12.08.2021 14:07, drug пишет: 12.08.2021 12:36, Learner пишет: > It seems that there is no easy way to transition from a postblit to a copy constructor, no? You just need both const and mutable copy ctors to replace inout one: ```D struct A { int[] data; this(ref return scope A rhs) { data = rhs.data.dup; } this(ref return scope const A rhs) const { data = rhs.data.dup; } } ``` the mutable copy ctor accepts mutable data and the const copy ctor accepts const and immutable data but using inout ctor is easier: ```D struct A { int[] data; this(ref return scope inout A rhs) /* no inout here */ { data = rhs.data.dup; } } ``` The problem is that if you qualify the ctor itself then if you pass const/immutable rhs to it then the ctor is const/immutable too (like the args) and of course you cannot modify this, so the error. To make a copy ctor you need to qualify copy ctor args as inout but the copy ctor itself shall be mutable and have no const,immutable or inout qualifier.
Re: I do not understand copy constructors
12.08.2021 12:36, Learner пишет: > It seems that there is no easy way to transition from a postblit to a copy constructor, no? You just need both const and mutable copy ctors to replace inout one: ```D struct A { int[] data; this(ref return scope A rhs) { data = rhs.data.dup; } this(ref return scope const A rhs) const { data = rhs.data.dup; } } ``` the mutable copy ctor accepts mutable data and the const copy ctor accepts const and immutable data
Re: I do not understand copy constructors
On 12/08/2021 9:36 PM, Learner wrote: It seems that there is no easy way to transition from a postblit to a copy constructor, no? struct Foo { this(ref Foo other) { foreach(i, v; other.tupleof) this.tupleof[i] = v; } @disable this(this); }
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 09:14:02 UTC, Paul Backus wrote: On Thursday, 12 August 2021 at 08:42:27 UTC, Learner wrote: struct A { int[] data this(ref return scope A rhs) { data = ths.data.dup; } } Generating an `inout` copy constructor for `struct B` failed, therefore instances of it are uncopyable What is an `inout` copy constructor? What should I change in A? When the compiler generates a copy constructor for a struct, it generates it with the following signature: ```d this(ref return scope inout(typeof(this)) src) inout ``` (Source: https://dlang.org/spec/struct.html#implicit-copy-constructors) Notice that both the `src` object and the object being constructed (`this`) are qualified with `inout`. `inout` is a special type qualifier that allows the same function to be used for mutable, `const`, and `immutable` arguments. To make this work, the compiler imposes heavy restrictions on what you can do with an `inout`-qualified object--only operations that are valid on mutable, `const`, *and* `immutable` objects are allowed for `inout`. (Source: https://dlang.org/spec/function.html#inout-functions) `A`'s copy constructor does not have any type qualifiers on its `rhs` argument or its `this` reference, so both default to mutable. In other words: `A`'s copy constructor can only be used to construct a mutable copy from a mutable original object. It *cannot* be used to construct an `inout` copy from an `inout` object. In order to make the generated copy constructor work, you need to give `A` a copy constructor that can copy `inout` objects. There are two possibilities here: 1. Make `A`'s copy constructor `inout`: `this(ref return scope inout A rhs) inout` 2. Make `A`'s copy constructor `const`: `this(ref return scope const A rhs) const` While option 2. is not working: struct A { int[] data; this(ref return scope const A rhs) const {} } Error: Generating an `inout` copy constructor for `struct A` failed, therefore instances of it are uncopyable Option .1 actually works, with an empty body, while it fails with the actual body: struct A { int[] data; this(ref return scope inout A rhs) inout { data = rhs.data.dup; } } Error: cannot implicitly convert expression `dup(cast(const(int)[])rhs.data)` of type `int[]` to `inout(int[])` It seems that there is no easy way to transition from a postblit to a copy constructor, no?
Re: I do not understand copy constructors
On Thursday, 12 August 2021 at 08:42:27 UTC, Learner wrote: struct A { int[] data this(ref return scope A rhs) { data = ths.data.dup; } } Generating an `inout` copy constructor for `struct B` failed, therefore instances of it are uncopyable What is an `inout` copy constructor? What should I change in A? When the compiler generates a copy constructor for a struct, it generates it with the following signature: ```d this(ref return scope inout(typeof(this)) src) inout ``` (Source: https://dlang.org/spec/struct.html#implicit-copy-constructors) Notice that both the `src` object and the object being constructed (`this`) are qualified with `inout`. `inout` is a special type qualifier that allows the same function to be used for mutable, `const`, and `immutable` arguments. To make this work, the compiler imposes heavy restrictions on what you can do with an `inout`-qualified object--only operations that are valid on mutable, `const`, *and* `immutable` objects are allowed for `inout`. (Source: https://dlang.org/spec/function.html#inout-functions) `A`'s copy constructor does not have any type qualifiers on its `rhs` argument or its `this` reference, so both default to mutable. In other words: `A`'s copy constructor can only be used to construct a mutable copy from a mutable original object. It *cannot* be used to construct an `inout` copy from an `inout` object. In order to make the generated copy constructor work, you need to give `A` a copy constructor that can copy `inout` objects. There are two possibilities here: 1. Make `A`'s copy constructor `inout`: `this(ref return scope inout A rhs) inout` 2. Make `A`'s copy constructor `const`: `this(ref return scope const A rhs) const`
I do not understand copy constructors
I have a structure like, used by other structures: struct A { int[] data; this(this) { data = data.dup; } } I am trying to upgrade it to use copy constructor: struct A { int[] data this(ref return scope A rhs) { data = ths.data.dup; } } Generating an `inout` copy constructor for `struct B` failed, therefore instances of it are uncopyable What is an `inout` copy constructor? What should I change in A?