Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't know how to construct class type 'S' with argument types '()' #54

Closed
timotheecour opened this issue May 21, 2015 · 5 comments · Fixed by #57
Closed

Don't know how to construct class type 'S' with argument types '()' #54

timotheecour opened this issue May 21, 2015 · 5 comments · Fixed by #57

Comments

@timotheecour
Copy link

Seems like msgpack-d requires empty constructor for classes.
Can we relax this?
Classes could be allocated without calling 'new' constructor to enable this.

@repeatedly
Copy link
Member

You mean Unpacker?
Unpacker's class deserialization requires arguments of constructor, not empty constructor.

object = new T(args);

Could you show me your code example?

@timotheecour
Copy link
Author

Yes, Unpacker.
Actually I'm not sure anymore.
Here's an example adapted from http://wiki.dlang.org/Memory_Management but without calling emplace (which has same restrictions as new, as does Object.factory apparently).

class A{
int x=2;
this(int x){
this.x=x;
}
}

void test(){
A a=allocClass!A;
// works but not sure how safe this is
}

T allocClass(T, Args...) (Args args) {
import core.stdc.stdlib : malloc;
import core.memory : GC;
auto size = __traits(classInstanceSize, T);
auto memory = malloc(size)[0..size];
assert(memory);

// instead of 0-fill, would fill up the buffer from deserialization
(cast(byte[])memory)[]=0;

GC.addRange(memory.ptr, size);
return cast(T)cast(void*)memory;
}

@timotheecour
Copy link
Author

Started a thread here: http://forum.dlang.org/thread/mailman.105.1432199217.7663.digitalmars-d-learn@puremagic.com [deserialization: creating a class instance without calling constructor]

Some proposed:

CT construct(CT, A...)(A a) if (is(CT == class)){
auto memory = malloc(typeid(CT).init.length);
memory[0 .. typeid(CT).init.length] = typeid(CT).init[];
return cast(CT) memory;
}

Although I think he meant this:

CT construct(CT)() if (is(CT == class)){
auto memory = malloc(typeid(CT).init.length);
memory[0 .. typeid(CT).init.length] = typeid(CT).init[];
return cast(CT) memory;
}

@repeatedly
Copy link
Member

I know we can use manual construction without new for classes.

Could you show me your code example?

This means I want to know what the code causes Don't know how to construct class type 'S' with argument types '()'.
But I noticed you call unpack like below:

class A
{
    this(int a) { }
}

A a;
unpacker.unpack(a, 10);  // ok
unpacker.unpack(a);  // error

Latter case is error prone but it seems acceptable. I will support it.

@timotheecour
Copy link
Author

Thanks, the patch works for DMD, however see my comments in the PR; it may not work for LDC compiler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants