I am trying to compile my wNim framework with gc:arc.
Here is the old code (simplified):
type
R = ref object of RootObj
data: int
var globalR {.global.} = R(data: 123)
proc final(r: R) =
echo "final: ", r.data
proc newR(): R =
new(result, final)
result.data = 456
echo "I need globalR: ", globalR.data
for i in 1..10:
var r = newR()
For now, this way may work:
type
R = ref O
O = object of RootObj
data: int
when defined(gcDestructors):
proc final(r: R)
proc `=destroy`(o: var O) =
final(cast[R](addr o))
var globalR {.global.} = R(data: 123)
proc final(r: R) =
echo "final: ", r.data
proc newR(): R =
when defined(gcDestructors):
result = R()
else:
new(result, final)
result.data = 456
echo "I need globalR: ", globalR.data
for i in 1..10:
var r = newR()
Is there a better way?
Yes, something like that. I added --gc:arc support with finalizers some weeks ago, and destructor support yesterday. Note that we do not really need destructors for ARC, finalizers are ok also, I added them because of the subclassing problem, see Araqs reply to filcuc and my last edit in
https://forum.nim-lang.org/t/5825#36241
You test with when defined(gcDestructors) while I do test with when compileOption("gc", "arc") -- I am not sure if both is the same. Note that you dont have to introduce the Value types explicitely just for ARC, we can write the destructors like this:
$ grep -A7 "=destroy" ~/.nimble/pkgs/gintro-0.7.1/gintro/gtk.nim
proc `=destroy`*(self: var typeof(SelectionData()[])) =
if not self.ignoreFinalizer and self.impl != nil:
boxedFree(gtk_selection_data_get_type(), cast[ptr SelectionData00](self.impl))
self.impl = nil
So typeof(SelectionData()[]) is the trick to get the value object type from reference type.
From
https://irclogs.nim-lang.org/23-02-2020.html#14:16:11
https://github.com/StefanSalewski/gintro/issues/66
it seems that your when defined(gcDestructors): is the more correct test, as when compileOption("gc", "arc") seems not to compile at all for old stable Nim. I think I will replace that, but maybe wait for Araq for confirmation, as I will not waste to much release numbers. 0.7.1 is already close to 0.9.9 unfortunately.
when compileOption("gc", "arc") seems not to compile at all for old stable Nim.
Wrap everything related to arc in the version check, e.g.:
when (NimMajor, NimMinor) >= (1, 1):
when compileOption("gc", "arc"):
....
That may work too.
But currently I consider replacing compileOption("gc", "arc") with defined(gcDestructors) because I have seen use of defined(gcDestructors) in Nim stdlib code. I am not sure if that is best -- all the options are a bit confusing.