-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Strange Table memory error #13430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
When you grow your table beyond its allocated size, it reallocates the seq used for storage. Use a TableRef, for starters, or provide a large enough initial size when creating the table. |
It may help to play with this shortened version of the original POC: import tables
const
n = 4
var table* = initTable[int, int](n)
for id in 1 .. n:
table[id] = id
proc inner() =
for id in n+1 .. n+n:
table[-id] = -id
proc outer*(table2: Table[int, int]) =
inner()
for k, v in table2.pairs:
echo k, "=", v
outer(table) |
Thank you for the work around. You are not implying that this is expected behavior, right? |
probably related (or caused) by #13431
I don't think this should be expected behavior notean alternative to using a TableRef is to pass by var instead, eg:
obviously, with different semantics |
It's expected behavior because you are passing a Use a |
I would like to argue that this should not be expected behavior. If this was really expected behavior, you are asking the user to understand the implementation details of Table. I feel like that is not reasonable, the whole point of programming languages in my opinion is the powerful abstractions they give us so we don't have to reason on those lower levels. And this breaks 2 of those abstractions that Nim implicitly promises. Specifically I expected that:
|
This is where it gets wrong, I think. Now I have to admit that I do not know the meaning of "clobbered", but what I would expect is:
Hence, modifying That said, most programming languages do not have the equivalent of |
I agree, IMO there's 0 performance benefit to having All that's needed is a way to deep-copy a |
https://nim-lang.org/docs/manual_experimental.html#aliasing-restrictions-in-parameter-passing For now, no bug here, aliasing is very hard and your code is bad. |
No.
|
Alternatively this is not a "won't fix" but it's waiting for a compiler that enforces the aliasing rules the manual mentions. Then the compiler will reject your code (as it should). |
you can with #13082 import tables
const t = {1:"foo", 2:"bar"}.newTable
doAssert $t == """{1: "foo", 2: "bar"}"""
doAssert t is TableRef
doAssert t[1] == "foo"
static: doAssert t[1] == "foo" I think we should re-open #13082 btw, see #13082 (comment); it removes an artificial limitation that makes more code work same at CT vs RT; I still haven't seen a fundamental blocker for this. |
It's fundamentally broken. |
if it's fundamentally broken, would you mind giving me a concrete example where the PR breaks / doesn't do what one would expect ? (again, not related to case objects which is a separate issue #13081) It only takes 20 seconds to build nim from #13082 with this 1 liner: git fetch origin pull/13082/head && git checkout FETCH_HEAD && nim c -d:release -o:bin/nim.temp1 compiler/nim.nim the example you had previously given me didn't do any crash for me see, #13082 (comment) |
It allows you to mix ref objects which have an header containing the refcount etc with "const" ref objects that lack these. |
Uh oh!
There was an error while loading. Please reload this page.
I encountered a strange error where the inner scope reference to a table becomes all zeros under very specific conditions.
I am not sure I can explain it better than the POC below:
https://play.nim-lang.org/#ix=2c2F
The text was updated successfully, but these errors were encountered: