strformat(or pairs) will free local var memory with refc
Description
The following code give wrong result: compile with --mm:refc and -d:danger I don't know it is the strformat or pairs problem, because change them will make the program run fine.
import strutils, strformat
proc get_all_codes(): seq[string] =
for i in 1..5000:
result.add align($i, 5, '0')
proc get_names(codes: seq[string]): seq[string] =
for code in codes:
result.add "abc" & code
proc check_codes() =
var lines: seq[string]
let codes = get_all_codes()
let names = get_names(codes)
# using for code in codes: , program run fine
# var i = 0
for i, code in codes:
var name = names[i]
#inc(i)
if code.len != 5:
# this should not be happened
echo "oops ", i, " ", code
quit()
# this line maybe the culprit
# change to:
# lines.add code & ":" & name
# seems fine
lines.add &"{code}:{name}"
echo "ok"
when isMainModule:
check_codes()
Nim Version
latest devel
Current Output
oops 245 abc00198
Expected Output
ok
Possible Solution
No response
Additional Information
No response
Only compile with msvc (any version) will generate the problem, use gcc doesn't.
@slangmgh What version of mvcc are you using?
msvc 2005 2008 2010 2013 2017 2019 32bit/64bit
add line GC_Ref(codes) before loop will prevent the bug happen.
Or add reference like echo codes.len before the proce return will prevent the bug happen too.
And the debug version is fine.
Most likely bug of msvc c optmizer. Possible generate the same code with for code in codes, which use pointer rather than object, and dont know it will fix the problem, but simple test run fine.
This is the gc bug with msvc compiler optimizer.
When the msvc optimizer the code, the variable codes is not on the stack (maybe in register, I doesn't check the assembler code yet), so the mark & sweep process think it is not referenced by any variable and free the memory.
The code in gc_common does check the register to find object reference, so I don't know why there is no reference to the object codes in any stack and register(In the msvc generated code, it store codes pointer in rsi).