Move and CTFE
Q. Schroll
qs.il.paperinik at gmail.com
Wed May 30 22:42:13 UTC 2018
On Wednesday, 30 May 2018 at 21:02:07 UTC, Jonathan M Davis wrote:
> On Wednesday, May 30, 2018 20:42:38 Q. Schroll via
> Digitalmars-d-learn wrote:
>> It seems one cannot std.algorithm.mutation.move objects
>> explicitly. Say I have a non-copyable type
>> [...]
>> It fails because move() cannot be executed at compile time. The
>> reason
>> "memcpy cannot be interpreted at compile time, because it
>> has
>> no available source code"
>> sounds very suspicious.
>
> Why is it suspicious? memcpy is a C function, and you can't
> call C functions during CTFE precisely because the compiler
> doesn't have their source code. You can't call D functions
> either if the compiler doesn't have their source (e.g. if
> you're using a .di file to hide the implementation).
I definitely do understand the error message and it makes sense
that it fails the way it's implemented. However, it makes no
sense that moving as a concept can fail at CTFE. That's what I
find suspicious. [Maybe 'suspicious' isn't the right term; I
couldn't express it better.] You can move rvalues at CTFE which
proves that the compiler can do it.
>> Shouldn't it be possible to move at CTFE,
>> too, or does it mean, non-copyable types are practically
>> unusable
>> for CTFE?
>
> You can't do much in the way of pointer or memory manipulation
> during CTFE (e.g. no pointer arithmetic or reinterpret casts).
> So, I don't see how a move could be done during CTFE. Even if
> the source for memcpy were available during CTFE, I suspect
> that it wouldn't be allowed due to the lower level stuff that
> it does.
That's the explanation why probably all currently possible
library alternatives to memcpy would fail. I suspected that when
encountering the error, but still wonder why memcpy or other
low-level stuff is even necessary to accomplish something the
compiler is perfectly able to do.
From what I see, the reason for the hack is lack of
expressiveness: We don't have rvalue-refs in D (which I find
good) so, currently, there is no cast-solution as in C++. So for
a proper move() that works at CTFE, we'd need some specific tool.
I have no idea of the details on how the compiler handles
lvalues. Would it make sense to add a compiler trait,
specifically to solve moving? Like __traits(move,
lvalue_expression) [name up for discussion] that is identical to
lvalue_expression with the exception that the (lvalue/rvalue)
flag (or whatever it is) is set to "rvalue". Basically, it's the
C++ solution: After the "cast", the compiler will proceed and
pretend it is an rvalue and therefore initiate moving.
Do you think adding a trait to make move() and swap() work at
CTFE is worth it?
A quick search showed me the class "Expression" has "virtual bool
isLvalue();" so it might be easy as wrapping and hooking that
virtual method. To me, [1] highly suggests that it works.
[1]
https://github.com/dlang/dmd/blob/master/src/dmd/expression.d#L1219
More information about the Digitalmars-d-learn
mailing list