type PtrStr = ptr object
str: string
var ptrstr1 = PtrStr(str: "hello")
causes this error: object constructor needs an object type.
if the type is ref object , it succeeds in making a ref object.
Is this syntax not supported for ptr object, or am I missing something?
is
var ptrstr1 = cast[PtrStr](alloc(sizeof(PtrStr)))
ptrstr1.str = "hello
the only way?In the real codebase, a function had 3600 recursions before crashing. (I'm bad at dynamic programming)
I figured it could be a stack overflow, so I created a "stack frame" variable with all the arguments and the inner variables, and to further reduce the stack size I wanted to use a pointer rather than an owned object. I ended up using a ref object and it worked well, but now I'm curious why ptr object type looks the same (and has fields), but doesn't work.
bonus question If a pass a large object (with many fields, seqs, strings,...) to a proc, does the stack grow by the objects's sizeof or by a pointer size?
By a pointer size. Do not use ptr to speed up parameter passing. It's not required and slightly harmful as it hinders Nim's optimizer to do its job. (Pointers introduce aliasing and that harms reasoning for everybody, compilers included.)
var ptrstr1 = cast[PtrStr](alloc(sizeof(PtrStr)))
Note: sizeof(PtrStr) is incorrect here. This should be the size of the object, not the pointer.
type
PtrStrObj = object
str: string
PtrStr = ptr PtrStrObj
let ptrstr1 = cast[PtrStr](alloc(sizeof(PtrStrObj)))
ptrstr1.str = "hello"
echo cast[uint](ptrstr1)
echo ptrstr1.str
Note: sizeof(PtrStr) is incorrect here. This should be the size of the object, not the pointer.
For some reason it works
I like your version more. I would like to add 2 comments.
since ptr object cannot be an object with fields, I would prefer it if it caused a syntax error (red squiggly lines in the ide )
I think let ptrstr1 = create PtrStr looks cleaner than cast alloc sizeof
Do not use ptr to speed up parameter passing.
Since the function is recursive, and creates a large object then passes it to itself, I wanted to allocate the object to the heap to shrink the stack frame, otherwise it crashed. I used ref object and it seems to work now, but I did change the logic to exclude some branches before recursing and now there are 700 recursions (rather than 3600), so it is no longer apples to apples.
I come from python, and this is the first time I had to try something like this, so I'm not sure my ideas are sound.
To answer your original question, just leave the ptr definition on the var instead because as Andrew noted you don't know which operation to allocate memory with. the solution is to use create() to put objects in your heap:
type someStr = object
str: string
var str1:ptr someStr = create(someStr)
keep in mind you have pointer which has no type by default, and ptr which needs a type.