I have the following program:
    
    
    import os
    import posix_utils
    import strformat
    import threadpool
    
    
    let tempRootPath = mkdtemp("vppdiff")
    
    proc xmiFilePath(fileNumber: int, cleaned: bool): string =
      let cleanedSuffix = "_cleaned"
      return tempRootPath / fmt"xmi{fileNumber}{cleanedSuffix}.xmi"
    
    var fv = spawn xmiFilePath(1, false)
    
    echo ^fv
    
    
    Run

When I try to compile it with Nim 1.0.0, I get 
    
    
    $ nim c --threads:on -r src/gcsafe_example.nim
    ...
    gcsafe_example.nim(13, 27) Error: 'spawn' takes a GC safe call expression
    
    
    Run

Looking at 
[https://nim-lang.org/docs/manual.html#threads-gc-safety](https://nim-lang.org/docs/manual.html#threads-gc-safety)
 , this is reasonable. Actually with a {.gcsafe.} block, as in 
    
    
    import os
    import posix_utils
    import strformat
    import threadpool
    
    
    let tempRootPath = mkdtemp("vppdiff")
    
    proc xmiFilePath(fileNumber: int, cleaned: bool): string =
      let cleanedSuffix = "_cleaned"
      {.gcsafe.}:
        return tempRootPath / fmt"xmi{fileNumber}{cleanedSuffix}.xmi"
    
    var fv = spawn xmiFilePath(1, false)
    
    echo ^fv
    
    
    Run

the program is compiled and seems to work.

Questions:

  * Have a understood the GC safety concept correctly in that this should 
_actually_ be safe? My reasoning is that tempRootPath is set once before 
xmiFilePath is called, so there shouldn't be any race condition or tempRootPath 
going away while xmiFilePath runs. Is this correct?
  * Would I get an error or at least a warning if using a {.gcsafe.} block 
actually wouldn't be safe?
  * If the answer to my first question is "yes", could Nim, maybe in a future 
version, recognize by itself that this usage is safe and accept the code 
without the {.gcsafe.} usage? _Should_ the compiler do this?
  * Is there more documentation on GC safety, for example an article, that 
would answer at least the first question? :-)


Reply via email to