CTFE, std.move & immutable

Dmitry Olshansky dmitry.olsh at gmail.com
Sat Nov 3 14:24:27 PDT 2012


I was looking to find a way to make std.algorithm.move CTFE-able. AFAIK 
it's not easy as it explicitly reinterprets data as chunk of bytes and 
that's something CTFE doesn't support at all.

So I went on and tried to just make a copy and then put write T.init 
into source, that's a copy and is somewhat fragile w.r.t. opAssign but 
should work.

And then...

std\algorithm.d(1563): Error: cannot modify struct source Data with 
immutable members
std\container.d(983): Error: template instance std.algorithm.move!(Data) 
error instantiating
std\container.d(1490):        instantiated from here: SList!(Data)
std\container.d(1490): Error: template instance 
std.container.SList!(Data) error instantiating

Strangely it moves a struct with a const field. In essence it can move 
immutable struct and will happily bit-blast it's previous location with 
T.init. That could be quite problematic...

Just for fun I tried this, kind shocked (and hit another bug in the 
compiler while writing it):

import std.algorithm;
struct C{ int dummy; }
struct S{
	immutable C c;
	int dummy;
	this(int x){
		c = C(x);
		dummy = x;
	}

	//to get T.init memcpy-ed over us
	this(this){}

	//uncomment this to the impenetrable:
	// Error: can only initialize const member c inside constructor	
	// And no line number ...
//	~this(){}
//curiously having ~this() without this(this) works but not together
}


immutable C a = C(36);
S s = S(47);

void main(){
	//auto x = move(a); //doesn't compile, pointer to immutable vs void* in 
memcpy
	//assert(a.dummy == 0);
//
	auto y = move(s);
	assert(s.c.dummy == 0); //yay! we've fooled typesystem
	assert(y.c.dummy == 47);
}


Soo... CTFE won't allow us to grossly break typesystem with an interpret 
cast. I believe we should forbid moving immutable/const stuff and honor 
the typesystem.

In any case for message passing (the prime use case) you still can move 
pointer to (slice of) immutable anyway?

P.S. I'm not first to discover this odd behavior of move...
A related pull request mentioning this problem among others: 
https://github.com/D-Programming-Language/phobos/pull/923

-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list