And has that changed recently?
I spend the whole weekend with
https://github.com/StefanSalewski/gintro/issues/167
Indeed I found a bug due to a tiny typo, but the cairo apps continue to crash with ARC. Before it was not crashing, maybe it leaked memory before. I have still no idea if Nim, Cairo or gintro has changed. My guess is Nim.
I just noticed that it crash wish
GC_unref(cast[RootRef](o))
but seems to work with the correct cast
GC_unref(cast[Surface](o)
If the correct cast is necessary now, then that may be a serious problem, as that statement is called from C library and so we do not know the correct type.
It is from
https://github.com/StefanSalewski/gintro/blob/master/gintro/cairoimpl.nim#L147
For reference, this is the crash I get with latest Nim compiler with wrong cast:
$ nim c --gc:arc drawingarea.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
..............................................................................................
CC: ../../home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairo.nim
Hint: [Link]
Hint: gc: arc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
202079 lines; 3.845s; 353.93MiB peakmem; proj: /tmp/hhh/drawingarea.nim; out: /tmp/hhh/drawingarea [SuccessX]
salewski@nuc /tmp/hhh $ ./drawing
salewski@nuc /tmp/hhh $ ./drawingarea
appStartup
Traceback (most recent call last)
/tmp/hhh/drawingarea.nim(339) drawingarea
/tmp/hhh/drawingarea.nim(337) test
/tmp/hhh/drawingarea.nim(306) newDisplay
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/gio.nim(31014) run
/home/salewski/Nim/lib/core/macros.nim(546) connect_for_signal_cdecl_configure_event2
/tmp/hhh/drawingarea.nim(151) dareaConfigureCallback
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairoimpl.nim(180) destroy
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairoimpl.nim(149) gcuref
/home/salewski/Nim/lib/system/arc.nim(211) GC_unref
/home/salewski/Nim/lib/system/arc.nim(171) nimDestroyAndDispose
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Segmentation fault (core dumped)
That is for
proc gcuref(o: pointer) {.cdecl.} =
GC_unref(cast[RootRef](o))
proc gcurefsurface(o: pointer) {.cdecl.} =
GC_unref(cast[Surface](o))
proc newContext*(target: Surface): Context =
fnew(result, gBoxedFreeCairoContext)
GC_ref(target)
result.impl = cairo_create(target.impl)
discard cairo_surface_set_user_data(target.impl, NUDK, cast[pointer](target), gcuref)
#discard cairo_set_user_data(result.impl, NUDK, cast[pointer](target), gcurefsurface)
With the correct cast all works.
The good news is that for the main gintro modules there is no problem, as all GC_unref() is used for GObject data type, so all casts are fine. For the cairo binding I could provide a own gcuref proc for each type, so that all casts are correct. Some more work, some more code. But I wonder why it worked for so many years. And I think it can work, as I can make my own GC_ref/GC_unref for RootRefs just by adding the refs to a a seq[RootRef]?
And this is the diff when I cast to Surface instead of RootRef:
@nuc /tmp/salewski/.cache/nim $ diff drawingarea_d/ crash/
diff drawingarea_d/drawingarea.json crash/drawingarea.json
4,9c4
< "compile": [
< [
< "/tmp/salewski/.cache/nim/drawingarea_d/@m..@s..@shome@[email protected]@spkgs@[email protected]@[email protected]",
< "gcc -c -w -fmax-errors=3 -I/home/salewski/Nim/lib -I/tmp/hhh -o /tmp/salewski/.cache/nim/drawingarea_d/@m..@s..@shome@[email protected]@spkgs@[email protected]@[email protected] /tmp/salewski/.cache/nim/drawingarea_d/@m..@s..@shome@[email protected]@spkgs@[email protected]@[email protected]"
< ]
< ],
---
> "compile": [],
diff drawingarea_d/@m..@s..@shome@[email protected]@spkgs@[email protected]@[email protected] crash/@m..@s..@shome@[email protected]@spkgs@[email protected]@[email protected]
40a41
> typedef struct RootObj RootObj;
111,112c112
< N_LIB_PRIVATE N_NIMCALL(void, GC_unref_OOZOOZhomeZsalewskiZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_720)(tyObject_SurfacecolonObjectType___u9boMgJzUmcT9bFvEdAxcViw* x);
< N_LIB_PRIVATE N_NIMCALL(void, eqdestroy__OOZOOZhomeZsalewskiZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_143)(tyObject_SurfacecolonObjectType___u9boMgJzUmcT9bFvEdAxcViw** dest);
---
> N_LIB_PRIVATE N_NIMCALL(void, GC_unref_OOZOOZhomeZsalewskiZOnimbleZpkgsZgintro4535v48O57O50ZgintroZgobject_160)(RootObj* x);
556,569d555
< N_LIB_PRIVATE N_NIMCALL(void, GC_unref_OOZOOZhomeZsalewskiZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_720)(tyObject_SurfacecolonObjectType___u9boMgJzUmcT9bFvEdAxcViw* x) {
< tyObject_SurfacecolonObjectType___u9boMgJzUmcT9bFvEdAxcViw* y;
< NIM_BOOL* nimErr_;
< nimfr_("GC_unref", "/home/salewski/Nim/lib/system/arc.nim");
< {nimErr_ = nimErrorFlag();
< y = (tyObject_SurfacecolonObjectType___u9boMgJzUmcT9bFvEdAxcViw*)0;
< nimln_(210, "/home/salewski/Nim/lib/system/arc.nim");
< y = x;
< nimln_(211, "/home/salewski/Nim/lib/system/arc.nim");
< eqdestroy__OOZOOZhomeZsalewskiZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_143(&y);
< if (NIM_UNLIKELY(*nimErr_)) goto BeforeRet_;
< }BeforeRet_: ;
< popFrame();
< }
573c559
< GC_unref_OOZOOZhomeZsalewskiZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_720(((tyObject_SurfacecolonObjectType___u9boMgJzUmcT9bFvEdAxcViw*) (o)));
---
> GC_unref_OOZOOZhomeZsalewskiZOnimbleZpkgsZgintro4535v48O57O50ZgintroZgobject_160(((RootObj*) (o)));
Binary files drawingarea_d/@m..@s..@shome@[email protected]@spkgs@[email protected]@[email protected] and crash/@m..@s..@shome@[email protected]@spkgs@[email protected]@[email protected] differ
I also did a small test program, but for that the parameter type of GC_unref() made no difference, it was working always fine.
Here is the valgrind output for the crash, but note that some of the reported errors are due to GTK, also shown for C GTK apps and not taken too serious by GTK devs.
salewski@nuc ~/hhh5 $ nim c --gc:arc -d:useMalloc drawingarea.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
............................................................................................
CC: stdlib_assertions.nim
CC: stdlib_digitsutils.nim
CC: stdlib_formatfloat.nim
CC: stdlib_io.nim
CC: stdlib_system.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/glib.nim
CC: stdlib_times.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/gobject.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/gio.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/cairo.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/gdk.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/gtk.nim
CC: drawingarea.nim
Hint: [Link]
Hint: gc: arc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
200616 lines; 3.875s; 353.566MiB peakmem; proj: /home/salewski/hhh5/drawingarea.nim; out: /home/salewski/hhh5/drawingarea [SuccessX]
[1]+ Done gedit ~/.nimble/pkgs/gintro-#v0.9.2/gintro/cairoimpl.nim
salewski@nuc ~/hhh5 $ ./drawingarea
appStartup
pattern =destroy
Context =destroy
Traceback (most recent call last)
/home/salewski/hhh5/drawingarea.nim(339) drawingarea
/home/salewski/hhh5/drawingarea.nim(337) test
/home/salewski/hhh5/drawingarea.nim(306) newDisplay
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/gio.nim(31014) run
/home/salewski/Nim/lib/core/macros.nim(546) connect_for_signal_cdecl_configure_event2
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairo.nim(35) dareaConfigureCallback
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairo.nim(30) =destroy
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairoimpl.nim(153) gcurefsurface
/home/salewski/Nim/lib/system/arc.nim(211) GC_unref
/home/salewski/Nim/lib/system/arc.nim(172) nimDestroyAndDispose
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Segmentation fault (core dumped)
salewski@nuc ~/hhh5 $ valgrind ./drawingarea
==2115== Memcheck, a memory error detector
==2115== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2115== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==2115== Command: ./drawingarea
==2115==
appStartup
==2115== Source and destination overlap in memcpy_chk(0x1ffeffd2d0, 0x1ffeffd2d0, 32)
==2115== at 0x4851C97: __memcpy_chk (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2115== by 0x4FC31A8: g_get_language_names_with_category (in /usr/lib64/libglib-2.0.so.0.6800.3)
==2115== by 0x4FEB31B: g_key_file_get_locale_string (in /usr/lib64/libglib-2.0.so.0.6800.3)
==2115== by 0x640C344: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115== by 0x640C5F0: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115== by 0x640CF65: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115== by 0x640D901: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115== by 0x641027D: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115== by 0x6410934: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115== by 0x6410D7E: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115== by 0x6429110: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115== by 0x634E482: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==2115==
pattern =destroy
Context =destroy
Traceback (most recent call last)
/home/salewski/hhh5/drawingarea.nim(339) drawingarea
/home/salewski/hhh5/drawingarea.nim(337) test
/home/salewski/hhh5/drawingarea.nim(306) newDisplay
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/gio.nim(31014) run
/home/salewski/Nim/lib/core/macros.nim(546) connect_for_signal_cdecl_configure_event2
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairo.nim(35) dareaConfigureCallback
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairo.nim(30) =destroy
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairoimpl.nim(153) gcurefsurface
/home/salewski/Nim/lib/system/arc.nim(211) GC_unref
/home/salewski/Nim/lib/system/arc.nim(172) nimDestroyAndDispose
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
==2115==
==2115== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==2115== at 0x49E927C: raise (raise.c:45)
==2115== by 0x10FFAB: signalHandler (in /home/salewski/hhh5/drawingarea)
==2115== by 0x49E931F: ??? (sigaction.c:10)
==2115== by 0x56339BF: ??? (in /usr/lib64/libcairo.so.2.11600.0)
==2115== by 0x111F2D: eqdestroy__OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZgobject_167 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x111FC0: GC_unref_OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZgobject_160 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x113B0D: gcurefsurface_OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_723 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x54E64B6: ??? (in /usr/lib64/libcairo.so.2.11600.0)
==2115== by 0x11318F: eqdestroy__OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_26 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x1138F5: eqsink__OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_49 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x11B5E5: dareaConfigureCallback_drawingarea_161 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x11B8E4: connect_for_signal_cdecl_configure_event2_drawingarea_561 (in /home/salewski/hhh5/drawingarea)
==2115==
==2115== Process terminating with default action of signal 11 (SIGSEGV)
==2115== General Protection Fault
==2115== at 0x4B795BD: __pthread_once_slow (pthread_once.c:114)
==2115== by 0x4AD63BE: __rpc_thread_variables.part.0 (rpc_thread.c:59)
==2115== by 0x4B14088: free_mem (in /lib64/libc-2.33.so)
==2115== by 0x4B13D49: __libc_freeres (in /lib64/libc-2.33.so)
==2115== by 0x483413E: _vgnU_freeres (in /usr/libexec/valgrind/vgpreload_core-amd64-linux.so)
==2115== by 0x3FF: ???
==2115== by 0x49E931F: ??? (sigaction.c:10)
==2115== by 0x56339BF: ??? (in /usr/lib64/libcairo.so.2.11600.0)
==2115== by 0x111F2D: eqdestroy__OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZgobject_167 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x111FC0: GC_unref_OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZgobject_160 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x113B0D: gcurefsurface_OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_723 (in /home/salewski/hhh5/drawingarea)
==2115== by 0x54E64B6: ??? (in /usr/lib64/libcairo.so.2.11600.0)
==2115==
==2115== HEAP SUMMARY:
==2115== in use at exit: 6,203,164 bytes in 27,412 blocks
==2115== total heap usage: 264,166 allocs, 236,754 frees, 21,937,229 bytes allocated
==2115==
==2115== LEAK SUMMARY:
==2115== definitely lost: 5,120 bytes in 8 blocks
==2115== indirectly lost: 26,165 bytes in 1,098 blocks
==2115== possibly lost: 6,660 bytes in 72 blocks
==2115== still reachable: 6,022,067 bytes in 25,010 blocks
==2115== of which reachable via heuristic:
==2115== newarray : 592 bytes in 12 blocks
==2115== suppressed: 0 bytes in 0 blocks
==2115== Rerun with --leak-check=full to see details of leaked memory
==2115==
==2115== For lists of detected and suppressed errors, rerun with: -s
==2115== ERROR SUMMARY: 78 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
salewski@nuc ~/hhh5 $
salewski@nuc ~/hhh5 $ nim c --gc:arc -d:useMalloc -d:noSignalHandler -g drawingarea.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
............................................................................................
CC: stdlib_assertions.nim
CC: stdlib_digitsutils.nim
CC: stdlib_formatfloat.nim
CC: stdlib_io.nim
CC: stdlib_system.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/glib.nim
CC: stdlib_times.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/gobject.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/gio.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/cairo.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/gdk.nim
CC: ../.nimble/pkgs/gintro-#v0.9.2/gintro/gtk.nim
CC: drawingarea.nim
Hint: [Link]
Hint: gc: arc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
200616 lines; 4.223s; 354.379MiB peakmem; proj: /home/salewski/hhh5/drawingarea.nim; out: /home/salewski/hhh5/drawingarea [SuccessX]
salewski@nuc ~/hhh5 $ ./drawingarea
appStartup
pattern =destroy
Context =destroy
Segmentation fault (core dumped)
salewski@nuc ~/hhh5 $ valgrind ./drawingarea
==3039== Memcheck, a memory error detector
==3039== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3039== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==3039== Command: ./drawingarea
==3039==
appStartup
==3039== Source and destination overlap in memcpy_chk(0x1ffeffd390, 0x1ffeffd390, 32)
==3039== at 0x4851C97: __memcpy_chk (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3039== by 0x4FC31A8: g_get_language_names_with_category (in /usr/lib64/libglib-2.0.so.0.6800.3)
==3039== by 0x4FEB31B: g_key_file_get_locale_string (in /usr/lib64/libglib-2.0.so.0.6800.3)
==3039== by 0x640C344: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x640C5F0: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x640CF65: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x640D901: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x641027D: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x6410934: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x6410D7E: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x6429110: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x634E482: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039==
pattern =destroy
Context =destroy
==3039==
==3039== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==3039== Bad permissions for mapped region at address 0x56339C0
==3039== at 0x56339C0: ??? (in /usr/lib64/libcairo.so.2.11600.0)
==3039== by 0x10E31B: nimDestroyAndDispose (arc.nim:172)
==3039== by 0x1122DA: eqdestroy__OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZgobject_167 (arc.nim:210)
==3039== by 0x11238D: GC_unref_OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZgobject_160 (arc.nim:211)
==3039== by 0x11308F: gcurefsurface_OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_723 (cairoimpl.nim:153)
==3039== by 0x54E64B6: ??? (in /usr/lib64/libcairo.so.2.11600.0)
==3039== by 0x113881: eqdestroy__OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_26 (cairo.nim:30)
==3039== by 0x1148A6: eqsink__OOZOnimbleZpkgsZgintro4535v48O57O50ZgintroZcairo_49 (cairo.nim:35)
==3039== by 0x1207B8: dareaConfigureCallback_drawingarea_161 (cairo.nim:35)
==3039== by 0x1209CA: connect_for_signal_cdecl_configure_event2_drawingarea_561 (macros.nim:546)
==3039== by 0x6657AD6: ??? (in /usr/lib64/libgtk-3.so.0.2404.25)
==3039== by 0x5180C47: g_closure_invoke (in /usr/lib64/libgobject-2.0.so.0.6800.3)
==3039==
==3039== HEAP SUMMARY:
==3039== in use at exit: 6,171,110 bytes in 27,209 blocks
==3039== total heap usage: 263,018 allocs, 235,809 frees, 21,695,073 bytes allocated
==3039==
==3039== LEAK SUMMARY:
==3039== definitely lost: 5,312 bytes in 11 blocks
==3039== indirectly lost: 26,165 bytes in 1,098 blocks
==3039== possibly lost: 5,988 bytes in 70 blocks
==3039== still reachable: 5,994,805 bytes in 24,833 blocks
==3039== of which reachable via heuristic:
==3039== newarray : 592 bytes in 12 blocks
==3039== suppressed: 0 bytes in 0 blocks
==3039== Rerun with --leak-check=full to see details of leaked memory
==3039==
==3039== For lists of detected and suppressed errors, rerun with: -s
==3039== ERROR SUMMARY: 78 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
salewski@nuc ~/hhh5 $
Edit nimbase.h so that
# define NIM_CONST /* disable const */
and see if it makes a difference. If it does, watch out what you do inside const sections, maybe this helps you to reproduce the problem in a self-contained example.
Will try.
Actually this issue is not too important for gintro and cairo, because for all the gobject based objects the cast is correct, and for cairo I can provide a uref() function for each cairo type with correct cast.
The question is more if the ref type of GC_unref() should matter for Nim 2.0. Because people writing bindings have to care for this, and when the type matters, then writing bindings may become harder.
But I assume that currently no one knows if GC_unref() will be available at all for Nim 2.0. I can remember years ago when ARC had no name and we discussed the Bacon/Dingle paper it was intended to fully remove GC_ref()/GC_unref() which would have been a really serious problem for bindings.
May the compiler already know the reason for the problem? Because compiler refuses to do a direct cast. Cast with intermediate pointer variable works, and that is what is used in the cairo bindings. So the compiler may have its reason to refuse the direct cast, but it does not tell us its reason.
type
Surface00* {.pure.} = object
Surface* = ref object
impl*: ptr Surface00
ignoreFinalizer*: bool
when isMainModule:
proc test =
var surf = Surface()
GC_ref(surf)
GC_unref(cast[RootRef](surf)) # Error: expression cannot be cast to RootRef=ref RootObj
var p: pointer = cast[pointer](surf)
#GC_unref(cast[RootRef](p)) # compiles
test()
Yes, I think this was really a bug in the bindings, and it may have been only a lucky incident that it worked all the years. Ref object and and RootRef is very different.
So I have to use
Surface* = ref object of RootRef
I think that was initially intented to allow subclassing.
I am still not sure is this is the same as
Surface* = ref object of RootObj
I guess it is the same?
I guess it is the same?
Correct.
The question is more if the ref type of GC_unref() should matter for Nim 2.0. Because people writing bindings have to care for this, and when the type matters, then writing bindings may become harder.
The type does matter but it does allow for subtyping (C++ would call it a "virtual" call). If you have inheritance enabled, there is a runtime type descriptor with the "correct" destructor. If you don't have inheritance enabled you can still get lucky but it's a bad idea.
But I assume that currently no one knows if GC_unref() will be available at all for Nim 2.0.
GC_unref stays and Nim 2.0 is nim c --gc:orc.
I can remember years ago when ARC had no name and we discussed the Bacon/Dingle paper it was intended to fully remove GC_ref()/GC_unref() which would have been a really serious problem for bindings.
The Bacon/Dingle thing is dead and won't come back but even with B/D the design did support refcounting. But it would have been more cumbersome to use.