digitalmars.D.learn - Should it compile?
- Jack Applegame (12/12) Jun 06 2020 Should it compile?
- Basile B. (5/17) Jun 06 2020 maybe it shouldn't but then with another message, for example
- Stanislav Blinov (13/21) Jun 06 2020 The moveEmpalce should compile, just like this does:
- Stanislav Blinov (3/4) Jun 06 2020 But not when the *first* argument is const though, like in the
- Jack Applegame (37/42) Jun 07 2020 The local variable is just an example.
- Paul Backus (2/5) Jun 07 2020 You can't move from a const variable.
- Stanislav Blinov (33/37) Jun 07 2020 Moving *from* a const would violate const. At least, until such
- MoonlightSentinel (3/4) Jun 06 2020 No, moveEmplace just sees a const reference and doesn't know that
- Jack Applegame (3/7) Jun 07 2020 Actually, it knows. Because moveEmplace assumes target is
Should it compile? ```d import std.algorithm.mutation; void main() { const char a = void; const char b ='b'; moveEmplace(b, a); // mutation.d: Error: cannot modify const expression target assert(a == 'b'); } ``` I think, it should.
Jun 06 2020
On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:Should it compile? ```d import std.algorithm.mutation; void main() { const char a = void; const char b ='b'; moveEmplace(b, a); // mutation.d: Error: cannot modify const expression target assert(a == 'b'); } ``` I think, it should.maybe it shouldn't but then with another message, for example Error, cannot `void` initialize a `const` declaration. since that makes very little sense, at least as a local variable. (as a member, this can be initialized in a constructor)
Jun 06 2020
On Saturday, 6 June 2020 at 11:58:06 UTC, Basile B. wrote:On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:The moveEmpalce should compile, just like this does: import std.conv : emplace; emplace(&a, 'a'); But, in the case of emplacing into a const, either should be system (moveEmplace is always system, but `emplace` for this case is not at the moment). One could do a emplace(&a, move(b)) but that's more moves (and I believe current emplace even would insert a spurious copy there). This is what we get for delegating emplacement and moves into a library instead of having appropriate intrinsics.Should it compile? I think, it should.maybe it shouldn't but then with another message, for example Error, cannot `void` initialize a `const` declaration. since that makes very little sense, at least as a local variable. (as a member, this can be initialized in a constructor)
Jun 06 2020
On Saturday, 6 June 2020 at 12:54:38 UTC, Stanislav Blinov wrote:The moveEmpalce should compile...But not when the *first* argument is const though, like in the example. For *that*, one would have to insert an additional cast.
Jun 06 2020
On Saturday, 6 June 2020 at 11:58:06 UTC, Basile B. wrote:maybe it shouldn't but then with another message, for example Error, cannot `void` initialize a `const` declaration. since that makes very little sense, at least as a local variable. (as a member, this can be initialized in a constructor)The local variable is just an example. I need to move a constant structure from one place in memory to another. I want to write something like C++ std::unique_ptr. Consider (this is not real code, but just a simple example): https://run.dlang.io/is/mUUU8c ``` import core.memory : pureMalloc, pureFree; import std.algorithm : move, moveEmplace; import std.traits : hasElaborateDestructor; struct NonCopyable { this(this) disable; } struct Unique(T) { this(this) disable; T* m_data; this(T data) { m_data = cast(T*) pureMalloc(T.sizeof); moveEmplace(data, *m_data); } ~this() { if(m_data) { static if(hasElaborateDestructor!T) (cast(Unqual!T*) m_data).__xdtor; pureFree(m_data); } } } void main() { NonCopyable a; auto ua = Unique!NonCopyable(move(a)); // fine const NonCopyable const_a; auto const_ua = Unique!(const NonCopyable)(move(ca)); // error, why??? } ```
Jun 07 2020
On Sunday, 7 June 2020 at 23:09:41 UTC, Jack Applegame wrote:const NonCopyable const_a; auto const_ua = Unique!(const NonCopyable)(move(ca)); // error, why???You can't move from a const variable.
Jun 07 2020
On Sunday, 7 June 2020 at 23:09:41 UTC, Jack Applegame wrote:auto const_ua = Unique!(const NonCopyable)(move(ca)); // error, why??? } ```Moving *from* a const would violate const. At least, until such time that the compiler is finally taught about move() (hopefully, sometime this decade). `move` and `moveEmplace` take arguments by ref. Therefore, if you call them with a const lvalue, arguments will be ref const. Which are allowed to bind to both mutable, const *and* immutable, and implementations of `move` and `moveEmplace` are not able to assume either way. Const is const. `emplace` violates const (it has to). Perhaps `moveEmplace` should also be allowed to violate const for its *second* argument, but not the first, on the assumption that the programmer knows what they're doing. Problem here is that, well, it wouldn't be as straightforward as it sounds, because the language allows overloading constructors based on `const` and `immutable`. So you may end up moving into a const such state that that const is not equipped to deal with: struct S { private { int i; bool iAmConst; } this(int i) { this.i = i; } this(int i) const { this.i = i; iAmConst = true; } } S mutableS = 42; const S constS = void; moveEmplace(mutableS, constS); // if this was allowed, now what? assert(constS.iAmConst); // <- this would fail An attempt was made to solve this (albeit the intended use case was different - impure moves), via DIP1014 and opPostMove. The DIP was even accepted. But apparently, it failed, for the above reason. Here's hoping that move constructors do make it into the language, so that these darker places of the standard library (or rather, runtime nowadays) may die in peace.
Jun 07 2020
On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:Should it compile?No, moveEmplace just sees a const reference and doesn't know that a is void-initialized.
Jun 06 2020
On Saturday, 6 June 2020 at 12:02:03 UTC, MoonlightSentinel wrote:On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:Actually, it knows. Because moveEmplace assumes target is uninitialized.Should it compile?No, moveEmplace just sees a const reference and doesn't know that a is void-initialized.
Jun 07 2020