I'm wrapping C code that returns owned cstring.
If I convert wrapped distinct cstring type to nim string, destructor is not
called. If I return distinct cstring type, destructor is called.
{.
emit: [
"""
char *allocCString() {
char *result = malloc(10 + 1);
strcpy(result, "HelloWorld");
return result;
}
"""
]
.}
proc rawWrapper(): cstring {.importc: "allocCString", cdecl.}
# -------------------------
type OwnedString = distinct cstring
proc `=destroy`(s: OwnedString) =
dealloc(s.cstring)
echo "Deallocating OwnedString"
func `$`(s: OwnedString): string {.borrow.}
proc idiomaticWrapper(): OwnedString =
rawWrapper().OwnedString
proc leakyWrapper(): string =
let ostring = rawWrapper().OwnedString
$ostring
# -------------------------
proc main() =
when true:
# destructor not called - definitely lost: 11 bytes in 1 blocks
# doesn't leak with --cursorInference:off
let s = leakyWrapper()
else:
# destructor called - All heap blocks were freed -- no leaks are
possible
let s = idiomaticWrapper()
echo s
main()
Run
--expandArc: leakyWrapper
var ostring_cursor
ostring_cursor = OwnedString(rawWrapper())
result = $ostring_cursor
-- end of expandArc ------------------------
Run
could you please explain what is happening here? if `$` generates a copy, why
ARC is not adding destructor call?