Hi All,
New to Nim (background is Go, Python, Java/C#, very rusty C) and struggling to understand the use for ptr object types.
The docs say
As a syntactical extension, object types can be anonymous if declared in a type section via the ref object or ptr object notations
This seems to work as I would expect using the constructor syntax for ref object types (the result is basically what you would consider a "normal" type in Java or a * type in Go, right?) - so I can mutate it in procs/methods without copying it.
type Person = ref object
name: string
var person = Person(name: "James")
echo person.name
But I am struggling to construct a ref object object. I either cannot construct it with a compiler error, or I get a SIGSEGV on the create()d memory at runtime. I can construct and take a pointer to a "normal" object just fine. So what is the use case for ptr object. This doesn't seem to be discussed in the docs at all.
type Cat = object
name: string
type DangerousCat = ptr object
name: string
enjoysMemoryLeaks: bool
# All good, can make pointer to normal object type
var cat = Cat.create()
cat[] = Cat(name: "Top Cat")
echo cat.name
dealloc(cat)
# Compile Error: object constructor needs an object type
var dangerCat = DangerousCat.create()
dangerCat[] = DangerousCat(name: "Garfield")
echo dangerCat.name
dealloc(dangerCat)
# SIGSEGV: Illegal storage access
var dangerCatSigSegV = DangerousCat.create()
dangerCatSigSegV.name = "Garfield"
echo dangerCatSigSegV.name
dealloc(dangerCatSigSegV)
PS. This is purely for curiousity, I know that the ptr stuff has very limited application in real life and I should be using ref for my objects (I guess like in Go, using *Struct instead of Struct 99% of the time unless it is a small struct staying locally in the current function...)
Thanks!
Wow quick replies, thanks :)
Is create() not just a convenience wrapper around alloc()? It looks like it just takes sizeof(T) for you to avoid you doing that yourself and then casts it nicely for you?
cast[ptr T](alloc0(sizeof(T) * size))
I was on that train of thought myself when I noticed echo DangerousCat.sizeof is 8 bytes/64 bits so the size of a pointer and not the size of the "underlying" struct itself.
Is there an easy way to get the sizeof the underlying type? Basically the same way you would do malloc() in C would be malloc(sizeof(DangerousCat)) and make DangerousCat not a ptr object... so I seem to have come full-circle on the "don't use ptr object" for type definitions argument!