Can wasMoved be overloaded?
wasMoved cannot be overloaded? I tried to overload wasMoved proc for my object type but it is ignored.
# testmove.nim
type
Foo = object
name: string
x: int
proc `=destroy`(x: var Foo) =
echo "Destory ", x.name, ": ", x.x
proc `=sink`(x: var Foo; y: Foo) =
echo "Sink to ", x.name, " from ", y.name
`=destroy`(x)
x.x = y.x
proc wasMoved(x: var Foo) =
echo "wasMoved ", x.name
x.x = -1
proc test =
var
a = Foo(name: "a", x: 1)
b = Foo(name: "b", x: 2)
a = b
echo a
test()
Compiled with following command:
nim c -r --mm:arc --expandArc:test testmove.nim
Program output:
Sink to a from b
Destory a: 1
(name: "a", x: 2)
Destory : 0
Destory a: 2
var
a
b
:tmpD
try:
a = Foo(name: "a", x: 1)
b = Foo(name: "b", x: 2)
`=sink`(a, b)
wasMoved(b)
echo [
:tmpD = `$`(a)
:tmpD]
finally:
`=destroy`(:tmpD)
`=destroy_1`(b)
`=destroy_1`(a)
There is wasMoved(b) in expandArc code, but compiler says testmove.nim(14, 6) Hint: 'wasMoved' is declared but not used [XDeclaredButNotUsed].
Background: I'm trying to wrap GMP. (I know there is already wrappers for the GMP: nim-gmp, bignum. But they don't use destructors.)
type
MPZ* = object
mpz: mpz_t
proc `=destroy`*(x: var MPZ) =
mpz_clear(x.mpz)
proc `=sink`*(x: var MPZ; y: MPZ) =
mpz_clear(x.mpz)
x = y
proc initMPZ*(): MPZ =
mpz_init(result.mpz)
GMP provides multiple precision integer type mpz_t. GMP manual says initialize mpz_t variable with the special initialization functions (mpz_init, mpz_init_set or etc) before using it and clear it out with mpz_clear when you’re done with a variable. It also says that the actual fields in mpz_t are for internal use only and should not be accessed directly by code that expects to be compatible with future GMP releases.
So just clearing all bits of mpz_t is directly writing the fields in mpz_t without using functions in GMP. In this case, I think wasMoved should use mpz_init instead of clearing all bits.
Move constructor in C++ class interface calls mpz_init(z.mp) to source object after it is moved: https://gmplib.org/repo/gmp/file/tip/gmpxx.h (ctrl + f with __gmp_expr(__gmp_expr &&z))
__gmp_expr(__gmp_expr &&z) noexcept
{ *__get_mp() = *z.__get_mp(); mpz_init(z.mp); }