I've sure read the documentation but I'm still unsure when these two commands are to be used.|
I'm interfacing with flex/bison, meaning bison calls Nim routines (with the tokens,ids,etc found), I create the appropriate AST objects and then control goes back to Bison.
For example, Bison calls:
$$ = argumentFromIdentifier($1);
and then in Nim:
proc argumentFromIdentifier(i: cstring): Argument {.exportc.} =
Argument(kind: identifierArgument, i: $i)
The thing is I suspect I'm doing something wrong. When compiling the project with anything other than
--gc:regions
, there are memory-related crashes.
Are cstring s the culprit?
GC_ref and GC_unref are required when your Nim code needs to be responsible for keeping track of memory, but you might end up passing things in and out of Nim code. In general they aren't used a whole lot for regular C interop. The important thing to keep in mind here is who is _allocating memory, and who is responsible for _freeing memory. When flex/bison passes you a cstring (actually a pointer to a buffer of characters, char *), you need to look at their documentation to see if it is you or them who should free it. If it's you, then you should import system/ansi_c and use c_free to free this pointer. When you create the Argument return type it's a similar story, not sure what flex/bison expects to get back but I assume a pointer to a struct of some kind. If you are responsible for free-ing this then you could use GC_ref before passing it to flex/bison, and then when you know that it is done with it you can do GC_unref, but more likely is it that flex/bison will free this when it's done with it. In that case you probably need to use something like this:
nim
result = cast[ptr Argument](c_malloc(sizeof(Argument)))