Thread overview | ||||||
---|---|---|---|---|---|---|
|
May 06, 2015 can't initialize .outer in inner class | ||||
---|---|---|---|---|
| ||||
Consider: void fun() { int x; class C { ... } } Objects of type C have access to x because they have an .outer pseudo-member. Problem is, emplace() and any other in-situ initialization techniques fail (e.g. emplace() will fail with inner classes). This seems to be a compiler issue - there's no way to initialize outer without calling new. What would be a proper fix to this? Thanks, Andrei |
May 06, 2015 Re: can't initialize .outer in inner class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 05/06/2015 10:01 AM, Andrei Alexandrescu wrote: > Consider: > > void fun() > { > int x; > class C > { > ... > } > } > > Objects of type C have access to x because they have an .outer > pseudo-member. > > Problem is, emplace() and any other in-situ initialization techniques > fail (e.g. emplace() will fail with inner classes). > > This seems to be a compiler issue - there's no way to initialize outer > without calling new. The following workaround seems to do it (I didn't test it thoroughly though, in particular, I didn't test whether escape analysis always works correctly for this implementation): T nestedEmplace(T,alias x,S...)(void[] mem,S args){ auto res=cast(T)mem.ptr; enum siz=__traits(classInstanceSize, T); (cast(byte[])mem)[0..siz]=typeid(T).init[]; auto dg=(){ return x; }; res.outer=dg.ptr; static if(is(typeof(res.__ctor(args)))) res.__ctor(args); else assert(!is(typeof(&res.__ctor))&&args.length==0); return res; } void main(){ int x=12345; class C{ this(){} int foo(){ return x; } } void[__traits(classInstanceSize,C)] mem=void; auto c=nestedEmplace!(C,x)(mem); assert(c.foo()==12345); x=3; assert(c.foo()==3); } > What would be a proper fix to this? > Probably nested types should invoke nested template instantiation, as the context pointer is runtime data. Then add a way to access the context pointer associated with some symbol (e.g. __traits). > > Thanks, > > Andrei |
May 06, 2015 Re: can't initialize .outer in inner class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 5/6/15 3:31 AM, Timon Gehr wrote:
> On 05/06/2015 10:01 AM, Andrei Alexandrescu wrote:
>> Consider:
>>
>> void fun()
>> {
>> int x;
>> class C
>> {
>> ...
>> }
>> }
>>
>> Objects of type C have access to x because they have an .outer
>> pseudo-member.
>>
>> Problem is, emplace() and any other in-situ initialization techniques
>> fail (e.g. emplace() will fail with inner classes).
>>
>> This seems to be a compiler issue - there's no way to initialize outer
>> without calling new.
>
>
> The following workaround seems to do it (I didn't test it thoroughly
> though, in particular, I didn't test whether escape analysis always
> works correctly for this implementation):
>
> T nestedEmplace(T,alias x,S...)(void[] mem,S args){
> auto res=cast(T)mem.ptr;
> enum siz=__traits(classInstanceSize, T);
> (cast(byte[])mem)[0..siz]=typeid(T).init[];
> auto dg=(){ return x; };
> res.outer=dg.ptr;
> static if(is(typeof(res.__ctor(args)))) res.__ctor(args);
> else assert(!is(typeof(&res.__ctor))&&args.length==0);
> return res;
> }
>
> void main(){
> int x=12345;
> class C{
> this(){}
> int foo(){
> return x;
> }
> }
> void[__traits(classInstanceSize,C)] mem=void;
> auto c=nestedEmplace!(C,x)(mem);
> assert(c.foo()==12345);
> x=3;
> assert(c.foo()==3);
> }
Thanks, that's quite the tour de force. I tried to massage things in various places to avoid changing emplace()'s signature, no avail. I think we have a problem here. -- Andrei
|
May 06, 2015 Re: can't initialize .outer in inner class | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr Attachments:
| 2015/05/06 19:35 "Timon Gehr via Digitalmars-d" <digitalmars-d@puremagic.com >: > > Probably nested types should invoke nested template instantiation, as the context pointer is runtime data. Then add a way to access the context pointer associated with some symbol (e.g. __traits). Related: https://issues.dlang.org/show_bug.cgi?id=8863 Kenji Hara |
Copyright © 1999-2021 by the D Language Foundation