February 25, 2014 Re: Struct constructor, opCall mess. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Tuesday, 25 February 2014 at 06:06:22 UTC, Jesse Phillips wrote:
> On Monday, 24 February 2014 at 20:35:54 UTC, Remo wrote:
>> This looks like D2 is still in Beta stadium and not really ready for production use !?
If someone thinks that C++ was production ready in 1998, just go and try a C++ compiler from this time.
|
February 25, 2014 Re: Struct constructor, opCall mess. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Remo | On Monday, 24 February 2014 at 19:41:57 UTC, Remo wrote:
> For Vector example this works pretty well this way.
> But my main problem is more complicated.
>
> extern(C) int init(ref CWrapper p);
> extern(C) void free(ref CWrapper p);
>
> struct CWrapper
> {
> //some data that must be the same at C side.
> Data m_data;
>
> this() {
> init(&this);
> }
> ~this() {
> free(&this);
> }
> }
>
> How to do something like this in D ?
> Using class appears for me to be wrong direction.
>
1) Please comment after previous speaker, not before.
You can't avoid default struct constructor problem if functions which you call in constructors are not at least CTFEable because you would need to call them if you wish to define default struct constructor. Since this is not your case, you can do:
2) You can use static OpCall, Voldemort type or alias this. In case of alias this it looks like:
extern(C) int printf(const char*, ...);
extern(C) int init(CWrapper* p) { printf("init\n"); return 0; }
extern(C) void d_free(CWrapper* p) { printf("free\n"); }
struct Data { void do_something(){} }
struct CWrapper
{
//some data that must be the same at C side.
Data m_data;
bool m_init;
/*this(int) {
init(&this);
}*/
~this() {
d_free(&this);
}
Data get()
{
if (!m_init)
init(&this);
return m_data;
}
alias get this;
}
void main()
{
CWrapper cw;
cw.do_something();
}
In case of Voldermort struct some struct is defined inside function, so the only way (in theory) to create an instance is to call that function. It is inconviniet but guarantees that you will not have non initialzed structs (in theory).
extern(C) int printf(const char*,...);
auto make_struct()
{
struct Data{}
struct CWrapper
{
extern(C) int m_init(CWrapper* p){ return 0; }
extern(C) void m_free(CWrapper* p){ printf("free\n");}
//some data that must be the same at C side.
Data m_data;
this(int) {
m_init(&this);
}
~this() {
m_free(&this);
}
}
return CWrapper(0);
}
void main()
{
auto x = make_struct();
}
4) Please do not define free() function.
|
February 25, 2014 Re: Struct constructor, opCall mess. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Monday, 24 February 2014 at 14:14:43 UTC, Tobias Pankrath wrote: > On Monday, 24 February 2014 at 13:56:01 UTC, Remo wrote: >> Hi, >> >> right now I am truing to figure out how the constructors behave in D2. >> >> Question 1: why it is not possible to create custom ctor for struct? > > The design of D relies on the fact that every type has a T.init property that is known to the compiler and used when in C++ the default ctor would get called. In constructors you can rely on (this == T.init), for example. > > You need to pick one T.init or default constructors and D picked T.init. The design of D relies on Andrei opinion. He is indeed convinced that default constructors are impossible. However, you can write "default constructor" right now like: struct S { Type t; this(int) { t = whather_is_callable_in_CTFE(); } } enum E : S { A = S(0) } void main() { E e; assert (e.t == whather_is_callable_in_CTFE()); } Since compiler does this, it can also accept straight syntax and semantic: struct S { Type t; this() // proxibited default constructor now { t = whather_is_callable_in_CTFE(); } } What D really lacks is ability to call function in runtime after struct instance creation like: struct S { @runtime this() {} ~this(){} } lowering to: S s; s.__runtime_ctor(); However, since compiler does this all over the place (postblits, copy constructors, destructors, etc.) There is no conceptual difference between having: S s s.__runtime_ctor(); and S s; s.__dtor(); In other words, there is no objective necessity not to have compile time and runtime default struct constructors since compiler already heavily does conceptually and technically similar things. |
February 25, 2014 Re: Struct constructor, opCall mess. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | On Tuesday, 25 February 2014 at 07:59:33 UTC, Maxim Fomin wrote: > On Monday, 24 February 2014 at 14:14:43 UTC, Tobias Pankrath wrote: >> On Monday, 24 February 2014 at 13:56:01 UTC, Remo wrote: >>> Hi, >>> >>> right now I am truing to figure out how the constructors behave in D2. >>> >>> Question 1: why it is not possible to create custom ctor for struct? >> >> The design of D relies on the fact that every type has a T.init property that is known to the compiler and used when in C++ the default ctor would get called. In constructors you can rely on (this == T.init), for example. >> >> You need to pick one T.init or default constructors and D picked T.init. > > The design of D relies on Andrei opinion. He is indeed convinced that default constructors are impossible. > > However, you can write "default constructor" right now like: > > struct S > { > Type t; > this(int) > { > t = whather_is_callable_in_CTFE(); > } > } > > enum E : S > { > A = S(0) > } > > void main() > { > E e; > assert (e.t == whather_is_callable_in_CTFE()); > } > > Since compiler does this, it can also accept straight syntax and semantic: > > struct S > { > Type t; > this() // proxibited default constructor now > { > t = whather_is_callable_in_CTFE(); > } > } > > What D really lacks is ability to call function in runtime after struct instance creation like: > > struct S > { > @runtime this() {} > ~this(){} > } > > lowering to: > S s; > s.__runtime_ctor(); > > However, since compiler does this all over the place (postblits, copy constructors, destructors, etc.) There is no conceptual difference between having: > > S s > s.__runtime_ctor(); > > and > > S s; > s.__dtor(); > > In other words, there is no objective necessity not to have compile time and runtime default struct constructors since compiler already heavily does conceptually and technically similar things. Thanks for all this replies. Now I have better idea how it supposed to work. Yes something like @runtime this() {} would be really great! https://d.puremagic.com/issues/show_bug.cgi?id=3438 > I think at some point we'll need to support default constructors that execute code. This was posted 2009-10-23 and now years later it is still not possible. :( Unfortunately this problems and workarounds makes porting C++ to D2 more complicated. Here are is also a small experiment that also show that 'ref' is also necessary in D2 just like in C++. There seems to be no optimization for this so using 'in' or nothing at all is slower and may have side effects. http://melpon.org/wandbox/permlink/FyaksIPW4u1dNpwh http://d.godbolt.org/#{%22version%22%3A3%2C%22filterAsm%22%3A{%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue%2C%22colouriseAsm%22%3Atrue}%2C%22compilers%22%3A[{%22sourcez%22%3A%22JYWwDg9gTgLgBAZxgEwHROcCBuAULgegIFcFgA7AczjCgpgDM4AjAUwGMBDU1uYeLjwSIQnADZjWUOJwQJWIZmICecdhGS9ZcAO50YrMeVT4kUYu3gBlXAG9ccR33LxgeJ3AdOYAC2AIACno%2BAEp7Dw9gOABePncIx1p6BgCAIis1GGg4AFIogB1yVIAaYBDsJy9HAF8qzw8iKAUIADcKaiamHyktcmQ4ZCzpHWAJFl4kl1Z%2BgGY4GFBWBBMPTrgMiDAAQTlgSnIAtfVyJACrEMQwuo9JxjSN7d39uELU8sqExyjY5bcvAEh%2Fk0YMQoOR5n4EHh%2FrUPHUAH6%2BfwBK6fW4pdIDIYvIrvD5OWq1XAtCDAfqiCgoux1DIIACM8UcRFpACYYutGetEHNYlYUZz6eyEDM8NUgAAA%3D%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fgdc%22%2C%22options%22%3A%22-O2%22}]} |
Copyright © 1999-2021 by the D Language Foundation