struct: default construction or lazy initialization.

bitwise via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jan 31 15:15:03 PST 2017


Unless I'm missing something, it seems that neither of these are 
actually possible.

Consider an object which needs internal state to function.
The obvious answer is to create it in the constructor:

struct Foo(T)
{
	T* payload;
	
	this() { payload = cast(T*)malloc(T.sizeof); }
	~this() { free(payload); }
	
	void foo() {
		// do something with payload that fails if not initialized
	}
}

But this is not possible in D, because structs can't have default 
constructors.

So one may think, I can use lazy initialization instead:

struct Foo(T)
{
	T* _payload;
	
	~this() { if(_payload) free(_payload); }
	
	@property T* payload() const {
		if(!_payload)
			(cast(Foo!T*)&this).payload = cast(T*)malloc(T.sizeof);
		
		return _payload;
	}
	
	void foo() {
		T* p = payload();
		// do something with payload that fails if not initialized
	}
	
	void bar() const {
		T* p = payload();
		// do something with payload that fails if not initialized
	}
}

So in C++, the above would be fine.
Since payload can never be perceived by the caller as 
uninitialized, the fact that it "breaks" const is irrelevant.

But you can't do this in D.

If the object is defined at module scope as shared static 
immutable, the compiler may put it in a readonly section of the 
executable which would cause an access violation upon trying to 
initialize it, and there is no way to prevent this from happening.

I'm hoping someone will tell me I'm wrong here, because the only 
alternative to the above approaches is to add boilerplate to 
_every_ _single_ _function_ that uses the payload in order to 
deal with separate cases where it's uninitialized.

Is there really no solution for this?


More information about the Digitalmars-d-learn mailing list