www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - fake RefCounted for CTFE?

reply Steven Schveighoffer <schveiguy gmail.com> writes:
I'm doing some stuff with RefCounted for a factory-like expression, 
where I expect the factory harnesses are going to be very short-lived. 
However, these don't work at CTFE (because malloc/etc aren't available).

Would it make sense for RefCounted to turn into GC for CTFE mode? That 
is, if RefCounted is used during CTFE, it just allocates on the GC heap 
and doesn't actually do ref counting. The end result will be a ref 
counted struct that somehow is flagged that it's never going away (and 
it shouldn't, if it's generated at compile time).

Then you could use functions that return RefCounted items as static 
initializers, or use libraries that use RefCounted at compile time 
without issues.

What do you think?

-Steve
Jun 15
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 15.06.20 23:18, Steven Schveighoffer wrote:
 I'm doing some stuff with RefCounted for a factory-like expression, 
 where I expect the factory harnesses are going to be very short-lived. 
 However, these don't work at CTFE (because malloc/etc aren't available).
 
 Would it make sense for RefCounted to turn into GC for CTFE mode? That 
 is, if RefCounted is used during CTFE, it just allocates on the GC heap 
 and doesn't actually do ref counting. The end result will be a ref 
 counted struct that somehow is flagged that it's never going away (and 
 it shouldn't, if it's generated at compile time).
 
 Then you could use functions that return RefCounted items as static 
 initializers, or use libraries that use RefCounted at compile time 
 without issues.
 
 What do you think?
 
 -Steve
I think it should work in CTFE, but it cannot break nogc.
Jun 15
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/15/20 5:39 PM, Timon Gehr wrote:
 On 15.06.20 23:18, Steven Schveighoffer wrote:
 I'm doing some stuff with RefCounted for a factory-like expression, 
 where I expect the factory harnesses are going to be very short-lived. 
 However, these don't work at CTFE (because malloc/etc aren't available).

 Would it make sense for RefCounted to turn into GC for CTFE mode? That 
 is, if RefCounted is used during CTFE, it just allocates on the GC 
 heap and doesn't actually do ref counting. The end result will be a 
 ref counted struct that somehow is flagged that it's never going away 
 (and it shouldn't, if it's generated at compile time).

 Then you could use functions that return RefCounted items as static 
 initializers, or use libraries that use RefCounted at compile time 
 without issues.

 What do you think?
I think it should work in CTFE, but it cannot break nogc.
Damn you're right. I can't think of a good way around that. All I can think of is a specialized function which allocates only in CTFE, and the compiler pretends it can be nogc. -Steve
Jun 15
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/15/20 8:23 PM, Steven Schveighoffer wrote:
 On 6/15/20 5:39 PM, Timon Gehr wrote:
 On 15.06.20 23:18, Steven Schveighoffer wrote:
 I'm doing some stuff with RefCounted for a factory-like expression, 
 where I expect the factory harnesses are going to be very 
 short-lived. However, these don't work at CTFE (because malloc/etc 
 aren't available).

 Would it make sense for RefCounted to turn into GC for CTFE mode? 
 That is, if RefCounted is used during CTFE, it just allocates on the 
 GC heap and doesn't actually do ref counting. The end result will be 
 a ref counted struct that somehow is flagged that it's never going 
 away (and it shouldn't, if it's generated at compile time).

 Then you could use functions that return RefCounted items as static 
 initializers, or use libraries that use RefCounted at compile time 
 without issues.

 What do you think?
I think it should work in CTFE, but it cannot break nogc.
Damn you're right. I can't think of a good way around that. All I can think of is a specialized function which allocates only in CTFE, and the compiler pretends it can be nogc.
Another suggestion I found on the issue tracker: https://issues.dlang.org/show_bug.cgi?id=18119 -Steve
Jun 15
prev sibling next sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Monday, 15 June 2020 at 21:18:23 UTC, Steven Schveighoffer 
wrote:

 a ref counted struct that somehow is flagged that it's never 
 going away
Something just doesn't seem quite convincing about that proposition ;)
Jun 15
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/15/20 7:08 PM, Stanislav Blinov wrote:
 On Monday, 15 June 2020 at 21:18:23 UTC, Steven Schveighoffer wrote:
 
 a ref counted struct that somehow is flagged that it's never going away
Something just doesn't seem quite convincing about that proposition ;)
In essence there's no reason to ref-count, because it lives in static data-land. -Steve
Jun 15
prev sibling next sibling parent reply tsbockman <thomas.bockman gmail.com> writes:
On Monday, 15 June 2020 at 21:18:23 UTC, Steven Schveighoffer 
wrote:
 Would it make sense for RefCounted to turn into GC for CTFE 
 mode? That is, if RefCounted is used during CTFE, it just 
 allocates on the GC heap and doesn't actually do ref counting. 
 ...
 What do you think?
Ref counting isn't only for memory management - sometimes it's used to ensure that a value's destructor will run at a logical point in time. Using the garbage collector during CTFE instead of malloc/free or whatever should be fine, but some thought would need to be put into whether there are any other valid uses of destructors during CTFE. The requirement that CTFE functions be pure at least forbids *most* other uses of destructors - for example, there is no need to close a file in CTFE, since you can't open one to begin with. But, does D's weak purity provably forbid *all* other valid uses of destructors? Making a bad assumption here could break code in really ugly and confusing ways, since CTFE is often triggered implicitly without any deliberate intent on the part of the programmer.
Jun 15
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/15/20 8:03 PM, tsbockman wrote:
 On Monday, 15 June 2020 at 21:18:23 UTC, Steven Schveighoffer wrote:
 Would it make sense for RefCounted to turn into GC for CTFE mode? That 
 is, if RefCounted is used during CTFE, it just allocates on the GC 
 heap and doesn't actually do ref counting. ...
 What do you think?
Ref counting isn't only for memory management - sometimes it's used to ensure that a value's destructor will run at a logical point in time. Using the garbage collector during CTFE instead of malloc/free or whatever should be fine, but some thought would need to be put into whether there are any other valid uses of destructors during CTFE.
Yeah, this is a good point. It could still run the destructor, but not free the memory. So instead of marking it as not truly ref-counted, just mark it as not needing to be freed. -Steve
Jun 15
prev sibling parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Monday, 15 June 2020 at 21:18:23 UTC, Steven Schveighoffer 
wrote:
 I'm doing some stuff with RefCounted for a factory-like 
 expression, where I expect the factory harnesses are going to 
 be very short-lived. However, these don't work at CTFE (because 
 malloc/etc aren't available).

 Would it make sense for RefCounted to turn into GC for CTFE 
 mode? That is, if RefCounted is used during CTFE, it just 
 allocates on the GC heap and doesn't actually do ref counting. 
 The end result will be a ref counted struct that somehow is 
 flagged that it's never going away (and it shouldn't, if it's 
 generated at compile time).

 Then you could use functions that return RefCounted items as 
 static initializers, or use libraries that use RefCounted at 
 compile time without issues.

 What do you think?

 -Steve
why not just have it continue doing ref-counting but use the GC to do the allocating? Can't use GC.malloc at ctfe but `new ubyte[](N)` works fine. You could even do a lambda cast to trick it in to being nogc.
Jun 16
parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Tuesday, 16 June 2020 at 13:36:28 UTC, John Colvin wrote:

 why not just have it continue doing ref-counting but use the GC 
 to do the allocating? Can't use GC.malloc at ctfe but `new 
 ubyte[](N)` works fine. You could even do a lambda cast to 
 trick it in to being nogc.
You can't. RefCounted (in Phobos, and any sane implementation otherwise) performs operations that simply aren't supported by CTFE. You can't do reinterpret casts in CTFE. You can't `new` a type with disabled default constructor. You can't properly initialize it if it has overridden opAssign. This is due to the sad deficiency of the language in that it doesn't define a form of placement new. There's a library solution, but it won't work in CTFE generically for the above reasons.
Jun 16