I've discovered that, given the following code:
    
    
    {.passC: "-fopenmp", passL: "-fopenmp".}
    for k in 1 || 10:
      echo k
    
    
    Run

If compiled with `--mm:refc`, it'd cause a segmentation fault (at the runtime). 
So it must be protected with a lock.
    
    
    {.passC: "-fopenmp", passL: "-fopenmp".}
    import locks
    var lock: Lock
    lock.initLock()
    for k in 1 || 10:
      lock.acquire()
      echo k
      lock.release()
    
    
    Run

And if the lock is added, it causes no error, no fault, even works without 
`--threads:on`, but if `--threads` is turned `on`, it'd cause a segmentation 
fault, which is very interesting.

Forthermore, if compiled with `--mm:orc`, the backend C compiler will output
    
    
    error: use of undeclared label 'BeforeRet_'
                    if (NIM_UNLIKELY(*nimErr_)) goto BeforeRet_;
                                                     ^
    1 error generated.
    
    
    Run

and stop compiling. (The same applies to `arc`.)

However, if compiled with `--mm:orc --exceptions:setjmp`, it'd pass the 
compilation, then cause a segmentation fault at the runtime, even if protected 
with exclusive locks.

I was about to open an issue, but I saw 
[this](https://github.com/nim-lang/Nim/issues/15703), which stopped me (because 
it seems to be a known issue) and caused me to use `--exceptions:setjmp`. Thus 
I discovered that if the 2nd version is compiled with `--mm:orc --threads:on 
--exceptions:setjmp`, it causes no error, no fault, even works without a lock. 
(That is, the 1st version can be compiled with this command, not causing a 
fault at runtime, but the output can be strange, as `echo` is not an atomic 
operation.)

My question is, why couldn't me find a documentation about this? The 
documentation of `||` did mention that it has some problems with GC, but not 
the C code compilation error and the workarounds.

Reply via email to